Hacker DirectoryHacker Directory

WEB / WEB-16.02

Configuration and secrets

Configuration arrives as input, which the application validates and consumes. Environment changes, running-process snapshots, and secret rotation are different events.

CORE · RED · BLUE · ARTIFACT · PRACTICE

1. Core · Mechanism

Read every scenario without motion

Valid config

  1. Synthetic input

    The example supplies mode=public and limit="2" as text inputs. Validation and process startup have not yet occurred.

    Startup input
    cfg-a; public; text "2"
    Config validator
    Not validated
    Running process
    Not started
    Dependency metadata
    Unused
  2. Local required check

    The validator locally checks required mode/limit fields and allowed enum public.

    Startup input
    cfg-a; public; text "2"
    Config validator
    Required/enum pass
    Running process
    Not started
    Dependency metadata
    Unused
  3. Local type check

    The decimal string "2" converts to integer 2 and satisfies the educational range 1..10.

    Startup input
    cfg-a; public; text "2"
    Config validator
    Typed limit=2; range pass
    Running process
    Not started
    Dependency metadata
    Unused
  4. Accept snapshot

    Validated cfg-a becomes one immutable snapshot; source text was not automatically typed.

    Startup input
    Source cfg-a
    Config validator
    Snapshot cfg-a limit=2
    Running process
    Not started
    Dependency metadata
    Unused
  5. Process consumes

    The local process consumes cfg-a/limit2 at startup and enters a separate local listening state.

    Startup input
    Source cfg-a
    Config validator
    Snapshot cfg-a limit=2
    Running process
    Listening; effective cfg-a limit=2
    Dependency metadata
    Unused
  6. Effective outcome

    The service records effective revision and harmless typed value without credential material.

    Startup input
    Source cfg-a
    Config validator
    Validated snapshot
    Running process
    Effective cfg-a limit=2
    Dependency metadata
    No secret value

Invalid type

  1. Synthetic bad text

    The limit input is the text "two" rather than a decimal integer. The process has not accepted this input or started listening.

    Startup input
    cfg-invalid; public; two
    Config validator
    Not validated
    Running process
    Not started
    Dependency metadata
    Unused
  2. Local enum check

    Mode public is valid while the limit type check has not completed.

    Startup input
    cfg-invalid; public; two
    Config validator
    Mode pass; limit pending
    Running process
    Not started
    Dependency metadata
    Unused
  3. Local type reject

    The decimal-integer rule rejects two without accepting a truthy string.

    Startup input
    cfg-invalid; public; two
    Config validator
    Rejected invalid-limit
    Running process
    Not started
    Dependency metadata
    Unused
  4. Startup stops

    Failed required validation prevents listening, so no request arrival is modeled.

    Startup input
    Invalid input retained
    Config validator
    No accepted snapshot
    Running process
    Not listening
    Dependency metadata
    Unused
  5. Failure outcome

    The harmless invalid-limit category is recorded without displaying a full environment dump.

    Startup input
    Invalid input retained
    Config validator
    Rejected
    Running process
    Startup rejected
    Dependency metadata
    No secret value

Version transition

  1. Old snapshot

    Initial source/consumer/accepted metadata is sec-ref-a, a noncredential alias.

    Startup input
    Source cfg-a
    Config validator
    Validated cfg-a
    Running process
    Consumer sec-ref-a
    Dependency metadata
    Accept sec-ref-a
  2. Source moves

    The supplied source moves to cfg-b/sec-ref-b while the running consumer retains its old snapshot.

    Startup input
    Source cfg-b sec-ref-b
    Config validator
    Old snapshot cfg-a
    Running process
    Consumer sec-ref-a
    Dependency metadata
    Accept sec-ref-a
  3. Revoke old version

    Supplied downstream acceptance changes to sec-ref-b only, separately from source-label rotation.

    Startup input
    Source cfg-b sec-ref-b
    Config validator
    Old snapshot cfg-a
    Running process
    Consumer sec-ref-a
    Dependency metadata
    Accept sec-ref-b; a revoked
  4. Old consumer reject

    The local metadata predicate finds old consumer a absent from the accepted set.

    Startup input
    Source cfg-b sec-ref-b
    Config validator
    Old snapshot cfg-a
    Running process
    Dependency unavailable
    Dependency metadata
    Old a rejected
  5. Validate replacement

    A new cfg-b snapshot with public/limit3 and sec-ref-b is separately validated.

    Startup input
    Source cfg-b sec-ref-b
    Config validator
    Validated cfg-b limit=3
    Running process
    Old consumer a
    Dependency metadata
    Accept sec-ref-b
  6. Replace snapshot

    The selected policy replaces one validated snapshot rather than automatically refreshing external environment.

    Startup input
    Source cfg-b sec-ref-b
    Config validator
    Validated cfg-b limit=3
    Running process
    Consumer sec-ref-b
    Dependency metadata
    Accept sec-ref-b
  7. New consumer accept

    The local metadata predicate accepts b without measuring vault cryptography or credential authentication.

    Startup input
    Source cfg-b sec-ref-b
    Config validator
    Validated cfg-b limit=3
    Running process
    Dependency available
    Dependency metadata
    New b accepted

ACTORS · STATE · DATA FLOW

Environment carries input, not a type contract

Environment variables are key/value inputs associated with the process startup environment. Node process.env exposes that process environment object; DotEnv parses additional values as text. The strings false, 0, or JSON-looking text do not automatically become booleans, numbers, or objects. Configuration loading must specify its input source and conversion to typed values.

The Atlas public-note service receives synthetic ATLAS_FIXTURE_MODE=public and ATLAS_FIXTURE_LIMIT="2". The application validates mode against an allowed enum and limit as a decimal integer in the selected educational range 1..10. This range is not production capacity advice. Successful validation produces normalized {mode:public,limit:2}; ordinary invalid text such as two is rejected, without relying on truthy strings.

Precedence among defaults, environment, and explicit overrides is an application contract, not a universal runtime priority. This example uses explicit input and records the accepted revision. Missing or invalid required input stops startup; do not animate request arrival before a server listens. Configuration does not replace database authorization or policy enforcement.

A running process has its own consumption lifecycle

Configuration can be read once at startup and converted to a frozen object. Moving a deployment source to cfg-b does not automatically refresh a running process using a cfg-a snapshot. This is not because environment is forever immutable: application code can change process.env. Read timing and reconstruction of cached clients or connections are application decisions.

Local Node process.env changes do not automatically update the parent shell or default Worker environment copies. Explicit shared-environment Worker options behave differently and are excluded here. Passing an explicit synthetic environment to a new child creates a new snapshot, not a remote control channel that updates the existing process.

Hot reload needs explicit revision, validation, and transition atomicity. Combining one new field with another old field creates mixed configuration. This example replaces a single validated immutable snapshot; restart or provider notification is not automatic in every application. Startup success, readiness, and dependency availability remain separate observations.

Secret delivery, use, and revocation differ

A secret is material whose exposure affects access or cryptographic protection; not every configuration field is secret. A public theme or limit differs from a database credential/private key. Environment injection can deliver a secret, but alone provides no vault, access control, encryption at rest, auditing, or rotation. Protect lifecycle separately across source repositories, build images, plaintext logs, and dumps.

Secret management controls versions, authorized consumers, rotation, revocation, and expiry. OWASP recommends least privilege and usage/audit metadata without logging values. Rotation depends on secret type and dependency; do not generalize one periodic policy to application service keys and human passwords. An old version can remain accepted downstream after rotation, so changing a source label is not equivalent to revocation.

The artifact carries only noncredential sec-ref-a/sec-ref-b aliases and accepted-version metadata. When the supplied source moves to b, the running process continues using a. A downstream accepting b and revoking a makes the old consumer dependencyUnavailable. A newly validated snapshot using b passes the selected dependency check. These states are neither real vault responses nor usable tokens; diagnosis needs no displayed secret value.

2. Red · Trust & Impact

Read every scenario without motion

Invalid startup

  1. The startup-input contract was selected

    ATLAS_FIXTURE_MODE=public and ATLAS_FIXTURE_LIMIT=two are fixed supplied inputs. No actual environment or secret file is read.

    Config/version source
    cfg-invalid input
    Consumer validation
    Type validation not performed
    Service/acceptance boundary
    Service not listening
  2. String and typed limits were separated

    The limit must be a decimal integer under educationalMin=1 and educationalMax=10. String two is not a numeric limit under this contract.

    Config/version source
    Raw limit="two"
    Consumer validation
    Decimal-integer gate failed
    Service/acceptance boundary
    Service not listening
  3. Startup acceptance was withheld

    startupOutcome remains rejected. A nonempty string being truthy does not establish that configuration type or enum validation passed.

    Config/version source
    Invalid public input
    Consumer validation
    Startup rejected
    Service/acceptance boundary
    Service not listening
  4. No default permission was manufactured

    This invalid input is not treated as replaced by "2" from validInput. Rejection does not establish an approved effective revision or policy authority.

    Config/version source
    cfg-invalid retained for diagnosis
    Consumer validation
    No normalized limit
    Service/acceptance boundary
    No accepted configuration
  5. The listening outcome was read separately

    listening=false is the negative execution boundary. The fixture explains input rejection; it measures no actual deployment, process crash or production availability.

    Config/version source
    Known: invalid limit
    Consumer validation
    Known: startup rejected
    Service/acceptance boundary
    Known: listening=false
  6. The configuration trust boundary was preserved

    An approved new snapshot is selected only after validation. Environment-delivery format or variable names do not prove trusted typed policy values.

    Config/version source
    No accepted snapshot
    Consumer validation
    Type gate remained closed
    Service/acceptance boundary
    No service activation claim

Old consumer

  1. The version-transition scope was selected

    secretVersions separates source, consumer and accepted aliases. sec-ref-a and sec-ref-b are not actual credentials; the artifact contains no secret value.

    Config/version source
    Version aliases only
    Consumer validation
    Consumer state not read
    Service/acceptance boundary
    No acceptance outcome
  2. Source rotation was read separately

    rotatedSource=sec-ref-b coexists with oldConsumer=sec-ref-a. A source change does not automatically refresh cached process-consumption state.

    Config/version source
    Source=sec-ref-b
    Consumer validation
    Old consumer=sec-ref-a
    Service/acceptance boundary
    No acceptance outcome
  3. The downstream accepted set was examined

    afterRevocationAccepted contains only sec-ref-b. This accepted set is supplied as a separate downstream-revocation outcome, not inferred from source rotation.

    Config/version source
    Source=sec-ref-b
    Consumer validation
    Consumer=sec-ref-a
    Service/acceptance boundary
    Accepted=[sec-ref-b]
  4. The old consumer was not accepted

    oldConsumerAccepted=false is the outcome of the selected transition. A stale version can cause dependency failure; this denial alone does not attribute secret compromise.

    Config/version source
    Source=sec-ref-b
    Consumer validation
    Consumer=sec-ref-a
    Service/acceptance boundary
    Old consumer accepted=false
  5. The new consumer remained a separate control

    newConsumer=sec-ref-b has newConsumerAccepted=true. This positive control does not mean the old process has already reloaded.

    Config/version source
    New source version known
    Consumer validation
    Old/new consumer contexts separate
    Service/acceptance boundary
    New accepted; old rejected
  6. Rotation was not equated with revocation

    The rotationImpliesRevocation=false boundary remains. Source, consumption and acceptance owners are verified separately; dumping every secret is unnecessary for this correlation.

    Config/version source
    Known: source b
    Consumer validation
    Known: consumer a
    Service/acceptance boundary
    Known: explicit downstream rejection

ASSUMPTION · BOUNDARY · CONTROL

Breaking text and snapshot assumptions

Accepting the strings false or two as truthy without converting to expected types can make mode/limit decisions incorrect. The broken assumption is that environment input is already normalized. Impact depends on how the application uses the field: wrong readiness, availability, or policy branches. This lesson rejects ordinary invalid input at startup without constructing an exploit payload or production-parameter recipe.

Assuming an old process adopted new config just because source revision changed creates a different failure. With cached cfg-a, deployed cfg-b metadata does not prove effective state. Record accepted revision and effective typed fields separately without secret values. Changed default/override precedence also needs verification rather than an assumption of unchanged behavior.

Do not confuse delivery with secret protection

Treating injected material as an automatically protected vault loses the access boundary. Evaluate required roles, source-read permission, and consumption context; dumping full configuration into plaintext logs can expose secrets. Impact depends on the secret privileges and consumer. Limit source access, separate values from output, and connect lifecycle to an operational inventory.

Assuming rotation and downstream acceptance occur together can break an old consumer or leave old versions unnecessarily valid. A source-current=b report alone cannot establish revoke=a. Obtain accepted/rejected metadata from the system enforcing revocation/expiry. Rejected alias a does not indicate compromise; it is the expected availability branch in this selected transition.

3. Blue · Secure development & defense

Read every scenario without motion

Effective snapshot

  1. The configuration-snapshot evidence was selected

    Initial validInput carries public/"2" and revision cfg-a. Effective configuration is separately normalized to typed limit=2.

    Config observation
    Input cfg-a
    Snapshot correlation
    Effective snapshot not read
    Evidence scope
    No refresh outcome
  2. The source change was read separately

    snapshotChange shows sourceRevisionAfter=cfg-b and sourceLimitAfter="3". Updated source text does not prove that the running snapshot changed.

    Config observation
    Source cfg-b / "3"
    Snapshot correlation
    Running snapshot under review
    Evidence scope
    No refresh outcome
  3. Running effective fields were compared

    runningRevision remains cfg-a with runningLimit=2. Accepted source revision and process-consumption time are separate evidence fields.

    Config observation
    Source cfg-b / "3"
    Snapshot correlation
    Running cfg-a / 2
    Evidence scope
    No automatic refresh
  4. The new validated snapshot was kept separate

    newValidatedRevision=cfg-b and newValidatedLimit=3 describe a separate outcome. Validation of this snapshot does not establish completed replacement of the old running process.

    Config observation
    New validated cfg-b / 3
    Snapshot correlation
    Running cfg-a / 2
    Evidence scope
    Replacement receipt not shown
  5. The selector sought a false-refresh claim

    The selector seeks automaticallyRefreshed=true while source and effective revisions differ. The main XML gives 0 and a separate positive fixture gives 1; neither is a secret audit stream.

    Config observation
    Source/effective difference known
    Snapshot correlation
    Main count=0; positive=1
    Evidence scope
    Claim scope explicit
  6. The effective-state conclusion was not broadened

    The fixture separates running cfg-a from validated cfg-b. It contains no actual environment scan, deployment or reload outcome for every consumer.

    Config observation
    Known: old running snapshot
    Snapshot correlation
    Known: new validated snapshot
    Evidence scope
    UNKNOWN: actual rollout

Observation gap

  1. The revision-observation scope was narrowed

    This branch reviews a scope containing only source-revision information. It does not substitute source for running state when effective-consumer observations are missing.

    Config observation
    Source metadata only
    Snapshot correlation
    Consumer observation missing
    Evidence scope
    No refresh conclusion
  2. Required selector fields were separated

    The selector requires the relationship among sourceRevision, effectiveRevision and automaticallyRefreshed. Source information alone cannot evaluate this predicate.

    Config observation
    Source metadata only
    Snapshot correlation
    Required consumer fields absent
    Evidence scope
    UNKNOWN: effective revision
  3. Missing and false remained distinct

    Without the consumer element or required fields, no definite automaticallyRefreshed=false value is produced. Missing observation is neither a successful nor failed reload record.

    Config observation
    Source metadata only
    Snapshot correlation
    Unknown, not a false refresh value
    Evidence scope
    UNKNOWN: effective revision
  4. Zero matches were not treated as a clean rollout

    Missing observations may produce no selector matches. Here count=0 does not prove that all consumers use cfg-b or that secret rotation completed.

    Config observation
    Source metadata only
    Snapshot correlation
    Selection coverage incomplete
    Evidence scope
    UNKNOWN: consumer update
  5. Benign metadata evidence was requested

    Consumer role, effective revision and observation time are required. Exporting credential values or the entire environment is unnecessary for this narrow correlation.

    Config observation
    Source metadata only
    Snapshot correlation
    Effective metadata required
    Evidence scope
    No secret export needed
  6. The missing-evidence conclusion was preserved

    The source change can be known while running consumption and downstream acceptance remain UNKNOWN. No outage or compromise cause is manufactured from this gap.

    Config observation
    Known: source metadata
    Snapshot correlation
    UNKNOWN: effective consumption
    Evidence scope
    UNKNOWN: downstream acceptance

IMPLEMENTATION · SECURITY CONTROL · VERIFICATION

Observe effective configuration without revealing values

Evaluate startup input against enum/type/required-field rules. Normal public/"2" normalizes to limit=2, while two rejects startup. Record accepted cfg-a separately from source cfg-b. Observe public mode and harmless limit fields without credentials. Missing-field observations do not automatically imply false or safe defaults.

Bind precedence and read timing to the service contract. For a startup snapshot, show that changing source environment does not refresh effective behavior; observe a new validated replacement/restart separately. Claims of process changes affecting parent or Worker copies need properly scoped evidence. Collect only needed harmless fields and revision metadata rather than real deployment environment dumps.

Track both owners of version transitions

Secret-source current alias, process-consumed alias, and downstream-accepted alias are different fields. Audit needs consumer role, outcome, version alias, and actual observation time without logging values. In the supplied current=b/process=a/accepted=b branch, rejection is explained by the old snapshot. Bind that conclusion to the downstream predicate rather than source-only rotation.

Verify the new version with its intended consumer and explicitly choose old-version acceptance and revocation ownership. Repairing dependency failure does not require giving everyone every secret: correct the selected consumer snapshot and permissions. Preserve the distinction between human-password and application-key rotation. This small metadata ledger does not prove a real vault encryption, access audit, or production rollout.

The artifact XPath selects automaticallyRefreshed=true claims when sourceRevision differs from effectiveRevision. A benign old snapshot yields 0; an incorrect refresh claim yields 1. This local XML check correlates source/current/effective fields and is not a secret-audit stream. A missing consumer element yielding0 remains insufficient evidence, not successful rotation.

NOW APPLY IT TO THE CASE

How do typing, snapshots and downstream acceptance differ?

Public configuration fields become a typed startup snapshot; secret-version aliases remain separate for source, consumer and accepted set.

Reconstruct decision order for input, server processing and response in the case. Parsed or valid data is not a completed operation; identify each owner and its condition.

Open the related case file ↗

READ THE EXAMPLE TOGETHER

Configuration and version-consumption ledger

Select a field and examine what it supports and where the evidence ends.

Read the raw artifact and field explanations
{
  "validationContract": {
    "modeEnum": [
      "public"
    ],
    "limitDecimalInteger": true,
    "educationalMin": 1,
    "educationalMax": 10,
    "precedence": "explicit supplied input only; no external env scan"
  },
  "validInput": {
    "ATLAS_FIXTURE_MODE": "public",
    "ATLAS_FIXTURE_LIMIT": "2",
    "revision": "cfg-a"
  },
  "normalized": {
    "mode": "public",
    "limit": 2,
    "revision": "cfg-a",
    "immutableSnapshotSupplied": true
  },
  "invalidInput": {
    "ATLAS_FIXTURE_MODE": "public",
    "ATLAS_FIXTURE_LIMIT": "two",
    "revision": "cfg-invalid",
    "startupOutcome": "rejected",
    "listening": false
  },
  "snapshotChange": {
    "sourceRevisionBefore": "cfg-a",
    "sourceRevisionAfter": "cfg-b",
    "sourceLimitAfter": "3",
    "runningRevision": "cfg-a",
    "runningLimit": 2,
    "newValidatedRevision": "cfg-b",
    "newValidatedLimit": 3
  },
  "secretVersions": {
    "aliasesAreCredentials": false,
    "initialSource": "sec-ref-a",
    "initialConsumer": "sec-ref-a",
    "initialAccepted": [
      "sec-ref-a"
    ],
    "rotatedSource": "sec-ref-b",
    "oldConsumer": "sec-ref-a",
    "afterRevocationAccepted": [
      "sec-ref-b"
    ],
    "oldConsumerAccepted": false,
    "newConsumer": "sec-ref-b",
    "newConsumerAccepted": true,
    "rotationImpliesRevocation": false,
    "valueStoredInArtifact": false
  },
  "selector": {
    "language": "XPath",
    "xml": "<observations><consumer sourceRevision=\"cfg-b\" effectiveRevision=\"cfg-a\" automaticallyRefreshed=\"false\"/></observations>",
    "xpath": "count(/observations/consumer[@sourceRevision!=@effectiveRevision and @automaticallyRefreshed=\"true\"])",
    "expected": 0,
    "positiveFixtureXml": "<observations><consumer sourceRevision=\"cfg-b\" effectiveRevision=\"cfg-a\" automaticallyRefreshed=\"true\"/></observations>",
    "positiveExpected": 1,
    "scope": "Only authored protocol-decision observations, not product log field names or a live HTTP capture.",
    "missingFieldBehavior": "Missing observation is insufficient evidence; zero matches is not proof of correct runtime behavior."
  }
}
validationContract / input
Only explicit synthetic text input; range is educational.
normalized / snapshotChange
Typed accepted state differs from source metadata.
secretVersions
Noncredential aliases and an acceptance-lifecycle predicate.

Inert metadata without process.env inventory, real credentials, or vault responses. Validation and snapshot policy are application-specific.

Two reality checks

Environment variables make configuration typed and secret-safe.

Values can be text; type validation and secret delivery/protection require separate decisions.

Changing a source secret version refreshes every running consumer and revokes the old one.

Consumer snapshots, source rotation, and downstream revocation have different owners and transitions.

YOUR TURN

Work through this story.

Predict the outcome, find the evidence boundary, and explain it in your own words.

ATLAS_FIXTURE_LIMIT is the string two. Does selected startup open a listener?

  1. No; startup is rejected and listening=false.
  2. Yes; invalid config is silently trusted through a default.
Read the explained answer

No; startup is rejected and listening=false. — The contract requires a decimal integer 1–10; a word value is not converted into a valid normalized limit.

The source changed to cfg-b/limit=3. Why does the running process still show cfg-a/limit=2?

Selected lesson artifact fields; teaching example

snapshotChange
{"sourceRevisionBefore":"cfg-a","sourceRevisionAfter":"cfg-b","sourceLimitAfter":"3","runningRevision":"cfg-a","runningLimit":2,"newValidatedRevision":"cfg-b","newValidatedLimit":3}
  1. Editing the source immediately changes every process.env value.
  2. The running snapshot is immutable; an explicit validated reload/new process is required.
Read the explained answer

The running snapshot is immutable; an explicit validated reload/new process is required. — Changing the source does not automatically update consumer memory; newValidatedRevision is a different state.

The secret source rotated to sec-ref-b. Why are old-consumer revocation and new-consumer adoption separate conditions?

Read the explained answer

The source may publish a new version while a consumer retains an old reference. When the authority narrows the accepted set to b, oldConsumerAccepted=false; a new consumer must adopt b. Rotation alone is not revocation. These aliases contain no credential bytes; no real environment or secret store was read.

□ I distinguished rotation, adoption and revocation.

□ I did not count an alias as actual secret material.

Open the application console · request / response / browser
Also open request, URL, cookie and DOM examples

Sources and scope