Security Architecture
How QuantumDeploy handles
your cloud credentials
QuantumDeploy never permanently possesses customer cloud credentials or infrastructure state. It borrows just enough power to execute one deployment, under constraints, and then lets it go.
Core Principle
The agent does not permanently own cloud power. It borrows scoped, time-bounded authority at execution time via native cloud trust primitives — then lets it go.
What we never store
Zero customer secrets in our systems
| Cloud access keys / secret keys / tokens | Never stored | Resolved at runtime, held only in process memory |
| Service principal secrets | Never stored | Fetched from your Key Vault at deploy time |
| Service account key files | Never stored | Impersonation tokens generated at deploy time |
| Terraform state files | Never stored | State lives in your Azure Blob, S3, or GCS bucket |
| Backend auth credentials | Never stored | Auth flows through workload identity and env vars |
What we store by reference
References only — never the actual secrets
| Azure credentials | Key Vault URI + secret names | Not the client ID, secret, or tenant ID values |
| AWS credentials | Role ARN + External ID | Not the access keys, secret keys, or session tokens |
| GCP credentials | Service account email + project | Not key files or OAuth tokens |
| State backend | Bucket / container / account names | Not access keys, SAS tokens, or auth credentials |
Cloud identity paths
Native cloud trust, not invented security
Pod has Managed Identity. Key Vault Secrets User role (read-only). Fetches SP credentials by secret name. ARM_* env vars for Terraform.
Pod has IAM Role via IRSA. AssumeRole with ExternalId (confused deputy protection). Session tags for CloudTrail attribution. Temporary credentials (max 1hr).
Pod has GCP SA binding. IAM Credentials API generateAccessToken on customer's SA. Short-lived OAuth token. No key files anywhere.
Execution architecture
One disposable runner per deploy
Control Plane
- ✓Stores references only
- ✓Issues signed runner tokens (HMAC-SHA256)
- ✓Creates K8s Jobs via client-go
- ✓Never resolves or transmits actual secrets
- ✓Records immutable evidence after each deploy
Runner Pod
- ✓Resolves credentials itself (workload identity)
- ✓Secrets exist only in process memory
- ✓Self-destructs after completion (TTL: 300s)
- ✓Non-root, bounded workspace, resource limits
- ✓No K8s API access (SA token not mounted)
Runner authentication
Signed, scoped, one-time-use tokens
HMAC-SHA256 signed
Cannot be forged without server secret
Deployment-scoped
Token for deploy A cannot access deploy B
Tenant-scoped
Token for tenant X cannot access tenant Y
Time-limited
Expires after deploy timeout + buffer
Replay-protected
Each nonce consumed once (Redis SET NX)
Key rotation
Current + previous key accepted during rotation
Secret redaction
Every output scrubbed before persistence
All Terraform output is pattern-matched and redacted before it reaches logs, databases, or your screen:
- ■Azure connection strings (AccountKey=, SharedAccessSignature=)
- ■AWS key IDs (AKIA*, ASIA*) and secret keys
- ■GCP OAuth tokens (ya29.*)
- ■Generic secret assignments (key = "...", password = "...")
- ■Environment variable patterns (ARM_CLIENT_SECRET=, AWS_SECRET_ACCESS_KEY=)
The ExecutionCredentials.Env field is tagged json:"-" — it cannot be serialized by the standard library. This prevents accidental persistence through JSON marshaling, debug logging, or audit record creation.
Deploy evidence
Tamper-evident records for every deployment
Every deploy produces an integrity-hashed evidence record containing:
State ownership
Your Terraform state stays in your cloud account
| Azure deploys | azurerm backend | Your storage account + container |
| AWS deploys | S3 backend | Your bucket + optional DynamoDB locking |
| GCP deploys | GCS backend | Your bucket + prefix |
Backend config values are passed via -backend-config CLI flags (non-sensitive location only). Sensitive backend keys like access_key, sas_token, and secret_key are rejected by the validation layer.
Preflight validation
Insecure setups blocked before first deploy
| Vault / role / SA accessible | Validate endpoint tests connectivity | Checked |
| ExternalId present (AWS) | Required — blocks deploy without it | Enforced |
| Subscription / region / project constraints | Validated before credential resolution | Checked |
| State backend has required fields | Blocks deploy without required config | Enforced |
| No sensitive keys in backend config | Rejects access_key, sas_token, etc. | Enforced |
| Credential ref format | Regex validation, no path traversal | Enforced |
Questions about our security architecture?
Contact security team