skip to content

An IaC tool creates a database with a generated password. Why does that plaintext password end up in the tool's recorded state, and what follows for how you store and access that record?

level: middleimportance: should knowfreq 48%

answer

  1. the record stores attributes, all of them
  2. a password is just another field
  3. marking sensitive hides output, not bytes
  4. classify the record by its worst secret
  5. a leaked record means rotation

basics

~20 s

The record stores every attribute the provider returned, and a generated password is just another attribute. Any recorded state therefore contains secrets in the clear, so its storage must be encrypted, tightly access-controlled and audited exactly like a secret store.

solid answer

~60 s

A state record is a snapshot of resource attributes, and the tool has no notion of which attributes are dangerous — a password, a private key, an initial access token and an instance size are all just fields it read back or sent. Sensitive inputs land there too, because a resource configured with a secret has that secret as part of its recorded configuration. Marking a value sensitive in most tools is a *display* control: it redacts terminal output and logs, and does nothing to the bytes on disk. The consequence is that the record inherits the classification of the most sensitive thing in it. Treat it as a secret store: encrypted at rest and in transit, read access restricted to the identities that actually run the tool, access logged, and never committed to git or attached to a build artefact. Reduce what lands there where you can — hand a resource a reference to a secret rather than the value — and if a record ever leaks, rotate everything it contained.

go deeper

for a junior

Know that generated passwords and keys are written into the tool's record in plain text, and that the record therefore must never be committed to git or pasted into a ticket.

for a middle

Explain the three routes a secret takes into the record — generated, supplied, looked up — and be precise that marking a value sensitive only redacts output and does not encrypt anything at rest.

for a senior

Show the controls you actually put on the storage: encryption with a managed key, read access limited to the running identity, object-level audit logs, and a rotation response if it ever leaks. Include version history and saved plans in the blast radius.

for a principal

Own the policy: which credentials are allowed to pass through infrastructure code at all, where the boundary sits between the IaC record and the secret store, how records are classified and retained, and what the organisation's rotation obligation is when one is exposed.

## Why the secret is in there at all The record's job is to remember what the tool built, which means storing the attributes of each object: the ones you supplied and the ones the provider returned. The tool has no way to distinguish a dangerous field from a boring one — both are just strings coming back from an API call. So when a resource generates a password, an initial credential, a private key, a bootstrap token or a connection string, that value is recorded like any other attribute, in the clear, inside the record. Secrets arrive by three routes: - **Generated by the provider.** An initial database password or an access key returned on creation. You often *need* it recorded, because it is the only copy. - **Supplied as input.** A password passed into a resource is part of that resource's recorded configuration. Passing it through a variable rather than a literal changes where it comes from, not where it ends up. - **Read by a lookup.** Fetching a value from a secret manager so the configuration can use it copies that value into the record too. Reading a secret with the tool is not a way to avoid recording it — it is a way to add another copy. ## Redaction is a display control The single most common misconception is that marking a value sensitive protects it at rest. In the mainstream tools it does not. Marking suppresses the value in plan output, in logs and in printed outputs — genuinely valuable, because CI logs are widely readable — but the record still stores the plaintext. Two consequences follow. Sensitive marking is a defence against *shoulder-surfing the pipeline*, not against someone who can read the record. And the absence of a mark does not mean a value is safe; nothing scans your record for secrets you never declared. ## What follows operationally The record's data classification is the maximum classification of anything inside it. Practically that means: **Encrypt it at rest and in transit.** Whatever holds it should be encrypted with a key you control, and reachable only over TLS. **Restrict read access to the identities that run the tool.** Not "the platform team", not "everyone with cloud read-only" — read on the record is equivalent to read on every secret it contains. This is the single control most often botched, because the storage is usually a general-purpose bucket or database that many roles can list. **Log access.** You want to be able to answer "who read this, and when" during an incident. Object-level audit logging on the storage is the cheap version. **Never commit it to version control**, and never attach it to a build artefact or a support bundle. It is the classic accidental disclosure: someone debugging a failure uploads the record to a ticket. **Watch the derivatives.** Saved plan files, backups and version history of the record carry the same values. Turning on versioning for recoverability means old secrets persist even after rotation, and a retention policy has to account for that. ## Reducing what lands there You cannot eliminate secrets from a record, but you can shrink the surface: - **Pass references, not values.** Where a service can resolve a secret at runtime, give it the identifier of the secret and let it fetch the value itself. The record then holds a pointer, and the value never enters it. - **Let the resource generate the credential and read it out of band.** Some resources write their generated credential directly to a secret manager, so the workload consumes it from there rather than from a tool output. - **Rotate immediately after creation.** If a value must be recorded to bootstrap, treat the recorded copy as expired: rotate the credential after provisioning, so what is in the record is no longer valid. - **Split what is truly sensitive out of the configuration entirely.** If a resource type forces a plaintext credential through the tool, that is an argument for provisioning it by another route. ## If a record leaks Treat it as a credential compromise, not a code leak. Enumerate every sensitive attribute the record contained — including in its version history — rotate each one, and check access logs for who could have read it. "It was only in a private bucket" is not a rotation policy; the point of enumerating is that most teams are surprised by what is in there. ## Stateless tools A tool that records nothing between runs has no such artefact, which is a genuine security advantage. Its secrets problem moves elsewhere: how the credential reaches the run in the first place, and whether it is echoed into logs. Different artefact, same discipline.

  • Doesn't marking an output sensitive keep the value out of the record?
    No — that is a display control. It redacts the value in plan output, in logs and in printed outputs, which matters because CI logs are widely readable, but the record still stores the plaintext attribute. Protecting it at rest is a property of where the record is kept: encryption, tight read access and audit logging, not of how the value is annotated in the code.
  • If reading a secret through the tool copies it into the record, how should a resource get one?
    Prefer a reference the consumer resolves at runtime: store the credential in a secret manager and give the resource or workload the secret's identifier, so only a pointer is recorded. Where a resource must be handed a value, let it generate the credential and write it straight to the secret store, or rotate immediately after provisioning so the recorded copy is already dead.
  • Your record's storage has versioning enabled for recoverability. What does that mean for secrets?
    Every historical version holds the plaintext values of its day, so rotating a credential does not remove it from the record's history. Versioning is worth keeping — it is your recovery path from a corrupted record — but the retention window is a security parameter as well as a recovery one, and every version needs the same encryption, access restriction and audit logging as the current object.

saying these in an interview costs you the question

  • Marking a value sensitive encrypts it in the state
  • Only outputs you print end up in the state
  • Reading from a secret manager keeps it out of the record
  • A private bucket is enough; no need to restrict reads
  • A leaked state file is just infrastructure metadata

context