Skip to content

AcuOps Security Guide

Credential Management

GitHub Secrets

All Acumatica credentials are stored as GitHub Secrets — encrypted at rest, never exposed in logs.

Secret Purpose
ACUMATICA_PROD_URL Production instance URL
ACUMATICA_PROD_USERNAME API user (dedicated service account)
ACUMATICA_PROD_PASSWORD API password
ACUMATICA_PROD_TENANT Tenant name

Never: - Write secrets to GITHUB_OUTPUT (they lose masking) - Print secrets in workflow logs - Commit credentials to the repository - Use personal accounts for CI/CD

API User Best Practices

  1. Create a dedicated API user for CI/CD (e.g., api-cicd)
  2. Assign minimum required role: Customization Administrator
  3. Do not grant access to financial data or reporting
  4. Rotate the password quarterly
  5. Monitor sessions in SM201030

Secret Rotation

# Rotate production password
gh secret set ACUMATICA_PROD_PASSWORD --body "new-strong-password"

Update the password in Acumatica first, then update the GitHub secret.

Code Security

Automated Security Scanning

The validator scans C# CDATA blocks for hardcoded credentials:

python scripts/validate-project.py Customization/_project/project.xml

Detected patterns: - Password = "..." — Hardcoded passwords - ConnectionString = "..." — Hardcoded connection strings - ApiKey = "..." — Hardcoded API keys - Secret = "..." — Hardcoded secrets - Token = "..." — Hardcoded tokens (20+ character base64)

Best Practices for Custom Code

  • Never hardcode credentials in C# extensions
  • Use Acumatica's built-in credential storage (SM201010)
  • Reference connection strings from web.config or environment
  • Use PXDatabase.Provider for database access (not direct SQL connections)

Pipeline Security

GitHub Actions

  • All action versions are pinned (@v4, not @latest)
  • Secrets are passed via env: blocks (not in command arguments)
  • Artifacts are retained for 30 days, then automatically deleted
  • Workflow permissions follow principle of least privilege

Network

  • Scripts only communicate with the specified Acumatica instance
  • No telemetry, analytics, or external service calls
  • HTTPS enforced for all API communication
  • Session cookies are temporary and cleaned up on exit (trap handler)

Dependencies

The pipeline has minimal dependencies:

Dependency Purpose Pinned
curl HTTP requests (bash scripts) System
base64 Package encoding System
zip Package creation System
python3 Validation, Python deployer 3.12
requests Python HTTP (deploy.py) >= 2.31.0
PyYAML Config loading (optional) >= 6.0.1

Audit Trail

Every deployment creates a record: - GitHub Actions run log (retained per org policy) - Deployment summary in GitHub Step Summary - Backup artifact (if enabled, 30-day retention) - Slack notification (if configured) - Acumatica System Monitor entry (server-side)