CareFlow Build JournalEntry 006
Delivery identity · July 7, 2026

The deployment credential we never stored.

CareFlow's first AWS pipeline used GitHub OIDC federation instead of a long-lived access key. Two failures made the final trust boundary easier—not harder—to explain.

01 · The missing secret

I wanted the pipeline to deploy without owning a permanent AWS key.

The familiar setup was easy to picture: create an access key, paste it into repository secrets, and remember to rotate it forever. Instead, I used OpenID Connect so a particular workflow could present a signed identity to AWS and receive temporary credentials for one role.

No long-lived AWS access key lived in GitHub. That removed a valuable credential from the list of things that could be copied, forgotten, or leaked.

02 · The exchange

The workflow was trusted because its claims matched—not because it came from GitHub.

The trust policy checked who issued the token, its audience, and the subject identifying the repository and Git reference. If those claims matched, AWS Security Token Service allowed AssumeRoleWithWebIdentity. If they did not, the exchange stopped.

03 · Two boundaries

Who may assume the role is not the same as what the role may do.

Trust policy

Who may become this role?

CareFlow bound trust to the intended repository and branch through the verified subject claim, with the audience restricted for AWS STS.

Permissions policy

What may the assumed role do?

The role received only the AWS actions required by that pipeline stage—not general administrator access.

A narrow permissions policy does not rescue an overly broad trust policy. A narrow trust policy does not excuse broad AWS permissions. Both questions need independent answers.

04 · Failure one

The first red check proved the quality gate was real.

terraform fmt

Failed on the first pipeline run.

This was not an identity failure. The check found a real formatting issue, and I fixed the code instead of weakening the gate.

A pipeline is not valuable because every run is green. It is valuable because the same expectations run before a change moves forward.

05 · Failure two

Machine identity made one character of difference matter.

The second failure reached AWS and returned Not authorized to perform sts:AssumeRoleWithWebIdentity. The repository and branch looked correct, but GitHub emitted the canonical lowercase organization name while the AWS exact-match condition used different casing.

repo:canonical-lowercase/name:ref:…
repo:Different-Case/name:ref:…

The safe fix was to inspect the actual subject and correct the exact condition—not introduce a wildcard until the error disappeared.

06 · The moving format

A correct trust-policy example can still expire.

GitHub introduced immutable identifiers in the default OIDC subject for repositories created after July 15, 2026, and for repositories renamed or transferred after that date. Existing repositories retain the earlier format unless they opt in.

The newer default appends immutable owner and repository IDs to the familiar names. That makes recycled names less dangerous, but it also makes some older tutorials an unreliable source of a literal subject string.

07 · Decision ledger

The pipeline removed a key without removing responsibility.

DecisionWhyStill required
OIDC federationAvoid stored long-lived AWS keysToken permission and exact trust
Repository + branch subjectNarrow which workflow identity is trustedVerify the emitted claim format
Minimal role actionsLimit impact after assumptionReview as pipeline capability grows
Keep failing checksMake controls enforce expectationsFix the cause rather than the gate
Core lesson

Trust the verified identity.

A machine identity is useful because its claims are exact, scoped, and testable.

Security lesson

Let credentials expire.

Short-lived role sessions remove the lifecycle of a permanent deployment key.

Debugging lesson

Inspect before broadening.

A claim mismatch calls for evidence, not a more permissive wildcard.

Delivery lesson

A red check can be success.

The first formatting failure showed the pipeline was enforcing its contract.

Field check

Before a workflow may assume an AWS role.

  1. Are issuer and audience conditions explicit?
  2. Was the actual subject claim previewed or inspected?
  3. Is trust limited to the smallest useful repository, branch, or environment identity?
  4. Are role permissions reviewed separately and kept least-privilege?
  5. Are actions, protected branches, environments, and audit logs part of the delivery boundary?
Primary sources

Documentation behind the implementation.

This entry is educational, not security, compliance, or operational advice. It describes a dated CareFlow implementation; verify current claim formats and provider guidance.

Visual edition

The deployment credential we never stored.

A narrated explanation of GitHub-to-AWS federation, the two policy boundaries, and the debugging evidence behind CareFlow's first keyless pipeline.

Short-lived AWS access, exact OIDC claims, and least-privilege delivery boundaries.