Repository navigation
sec(iac/aws): require OIDC subject claim in the federation bundle generator - #1691
Conversation
📝 WalkthroughWalkthroughAWS federation IaC generation now validates and propagates OIDC subject claims across CLI, CloudFormation, Terraform, and standalone generator outputs. AWS WIF trust policies always include a subject condition. ChangesAWS OIDC subject claim enforcement
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Operator
participant FederationGenerator
participant AWSWIFBundle
participant AWSIAM
Operator->>FederationGenerator: Provide --oidc-subject-claim
FederationGenerator->>FederationGenerator: Validate claim and target/source combination
FederationGenerator->>AWSWIFBundle: Render validated claim
AWSWIFBundle->>AWSIAM: Create resources with :sub-restricted trust policy
Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai full review |
✅ Action performedFull review finished. Your included review limit is currently reached under our Fair Usage Limits Policy. Your recent PR review activity is in the 95th percentile or higher among CodeRabbit users, so adaptive limits apply. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 5 minutes. |
65fefaa to
1d9e85b
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
known_issues/13_iac_aws_target.md (1)
5-57: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winMove the resolved
#1640record toknown_issues/resolved/.Lines 44-57 mark
#1640as resolved, but its record remains underknown_issues/. Extract the resolved record intoknown_issues/resolved/and retain the active#1689finding in this document.As per coding guidelines, “When a referenced GitHub issue closes, move its known-issue document to
known_issues/resolved/in the same PR; do not delete it.”🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@known_issues/13_iac_aws_target.md` around lines 5 - 57, Move the resolved `#1640` record from this document into a separate document under known_issues/resolved/, preserving its full content and resolution details. Update this document to retain only the active `#1689` finding, without deleting the original issue record.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/iacfiles/templates_test.go`:
- Around line 209-247: Extend TestAWSWIFCLI_SubjectClaimRequired to execute the
rendered Bash script for empty, whitespace, $, and * OIDC_SUBJECT_CLAIM values
using a temporary file and a mock aws executable. Assert each run exits non-zero
and the mock aws command is never invoked, while preserving the existing
rendered-text assertions.
In `@scripts/generate-federation-iac.go`:
- Around line 287-292: Update populateData and the standalone generator’s
--oidc-subject-claim handling to reject empty values and any whitespace, $, or *
characters before storing the input. Preserve the raw claim for JSON and
Terraform rendering, but provide a shell-escaped copy to the AWS CLI template,
following the existing pattern in handler_federation.go so embedded quotes and
backticks cannot execute commands.
---
Outside diff comments:
In `@known_issues/13_iac_aws_target.md`:
- Around line 5-57: Move the resolved `#1640` record from this document into a
separate document under known_issues/resolved/, preserving its full content and
resolution details. Update this document to retain only the active `#1689`
finding, without deleting the original issue record.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: e790e147-7a70-42f5-b03f-0ad716101497
📒 Files selected for processing (9)
internal/api/handler_federation.gointernal/api/handler_federation_test.gointernal/iacfiles/templates/aws-cfn-deploy.sh.tmplinternal/iacfiles/templates/aws-wif-cf-params.json.tmplinternal/iacfiles/templates/aws-wif-cli.sh.tmplinternal/iacfiles/templates/aws-wif.tfvars.tmplinternal/iacfiles/templates_test.goknown_issues/13_iac_aws_target.mdscripts/generate-federation-iac.go
…erator PR #1602 made OIDCSubjectClaim a required CloudFormation parameter with no default, closing the subject-less AWS trust policy hole for the checked-in template. The internal/iacfiles generator that produces the customer-facing bundle was left untouched at the time (internal/ was owned by concurrent in-flight branches), so three bundle formats still shipped a subject-less policy or a broken deploy: - aws-wif-cli.sh.tmpl documented OIDC_SUBJECT_CLAIM as "Optional" and built a trust policy with only the :aud condition when it was unset. This path never goes through CloudFormation and format=cli is a first-class user-selectable download, so it was the one exploitable gap: any identity the documented issuer (accounts.google.com) can mint could assume the role and place irreversible multi-year commitment purchases. - aws-cfn-deploy.sh.tmpl and buildCFParamsJSON never forwarded OIDCSubjectClaim, so the CFN deploy failed at change-set creation with "Parameters: [OIDCSubjectClaim] must have values" once the parameter became required. - aws-wif.tfvars.tmpl emitted oidc_subject_claim commented out and labelled "Optional", contradicting the Terraform module's required, no-default variable. Fix: aws-wif-cli.sh.tmpl drops the subject-less else branch entirely and validates OIDC_SUBJECT_CLAIM (non-empty, no whitespace/$/*) before making any AWS call, mirroring the guard PR #1602 added to the CloudFormation parameter. federationIaCData gains an OIDCSubjectClaim field threaded through shellEscapeData, buildCFParamsJSON, aws-wif-cf-params.json.tmpl, aws-cfn-deploy.sh.tmpl's --parameter-overrides, and aws-wif.tfvars.tmpl (uncommented, "Optional" label removed). The standalone scripts/generate-federation-iac.go mirror gains the same field plus an --oidc-subject-claim flag. CUDly's server has no generic way to know the calling workload's real subject claim, unlike OIDCIssuerURL/OIDCAudience which are derivable from target/source alone, so the value stays operator-supplied by design — every artifact now requires it explicitly instead of defaulting to a working-but-insecure empty value. Closes #1640.
Follow-up to d4776cc — the known_issues entry was written before the PR existed and used a placeholder.
The standalone federation IaC generator copied --oidc-subject-claim straight
onto iacData with no validation and no escaping. The value is then interpolated
verbatim into three different grammars the script renders:
- Bash: aws-cfn-deploy.sh.tmpl builds a "OIDCSubjectClaim=<value>" double-quoted
word passed to `aws cloudformation deploy`, so a command substitution or a
quote executes when the operator runs the generated deploy-cfn.sh.
- JSON: aws-wif-cf-params.json.tmpl, where a quote injects extra parameter keys
into the CloudFormation parameters file (a second RoleName entry, for one).
- HCL: aws-wif.tfvars.tmpl, where a quote breaks out of the attribute value.
Escaping is the wrong primary control here: no single escaping helper is correct
for all three grammars, and for the ${VAR:-<value>} interpolation contexts the
in-script guard runs after the assignment that embeds the value, so a command
substitution has already executed by the time it is inspected. Validate at the
Go boundary instead, before anything is rendered.
The check is a positive allowlist, ^[A-Za-z0-9][A-Za-z0-9._:/@=+-]*$ with a
255-byte cap. It is deliberately stricter than the ^[^\s*$]+$ AllowedPattern the
CloudFormation template and Terraform module enforce on the same value: those
validate a value that is already a typed parameter and only need to reject what
IAM mishandles, while this one validates a value about to become shell, JSON and
HCL source. The narrowing costs nothing here because awsOIDCIssuer emits only
accounts.google.com, login.microsoftonline.com, or "" for an unrecognised
source, so the subjects reachable through this script are a numeric string and a
UUID.
Also close the inverse fail-quiet case found while wiring this: the flag was only
read on the AWS arm, so passing it with --target gcp, or with the aws->aws
cross-account combination whose role is trusted by source account plus external
ID rather than by an OIDC :sub condition, discarded it silently. An operator who
typos --target would get an artifact pinning nothing while believing
otherwise. A subjectClaimMode enum now distinguishes required from
not-applicable, with the strict value as the zero value so an unset mode fails
closed, and populateData returns error rather than bool. --target is checked
against an allowlist before the claim is, so a typo there is still reported as a
bad --target rather than as an inapplicable flag.
internal/iacfiles/templates/README.md is updated to match: its four AWS-WIF
examples were copy-pasteable invocations that are now hard errors. It also spells
out that the flag not applying to a combination does not mean that bundle needs
no pinning, with a per-source table of the required variable each GCP target
emits (aws_role_name, oidc_subject, or source_service_account).
Tests, both confirmed to fail against the pre-fix code:
- scripts/generate_federation_iac_test.go compiles the //go:build ignore script
once and exercises it as a subprocess. 16 hostile values, the missing-value
case, bundle mode, the four not-applicable combinations, and 6 positive
controls. Ordering is proved directly by pointing --templates-dir at an empty
directory: a render attempt would fail with "no such file", so the validation
error instead is proof nothing was read.
- internal/iacfiles/templates_test.go now executes the rendered aws-wif-cli.sh
against a recording stub `aws` placed on the child's PATH, asserting both a
non-zero exit and zero AWS invocations for every invalid OIDC_SUBJECT_CLAIM,
plus a positive control that checks the accepted value actually reaches the
trust policy's :sub condition. Against the pre-fix template this shows a role
being created with a :aud-only condition, which is #1640 end to end.
Adjacent pre-existing gaps found and filed on #1690 rather than fixed here:
iacData is missing four fields the templates reference, shellEscape does not
escape '}', and two server-side render paths emit shell/HCL from unescaped data.
Refs #1640
1d9e85b to
68a47c0
Compare
Rebased onto current
|
| Command | Exit |
|---|---|
go build ./... |
0 |
go vet ./... |
0 |
go test -count=1 ./internal/iacfiles/... ./internal/api/... ./scripts/... |
0 (2093 tests) |
golangci-lint run --timeout=10m ./... (CI-pinned v2.10.1) |
0, 0 issues. |
gocyclo -over 10 $(git ls-files "*.go" | grep -v _test.go | grep -v vendor/) |
0, no output |
bash -n on all 18 rendered scripts |
0 |
shellcheck -s bash on all 18 rendered scripts |
0 |
populateData is at complexity 8, validateOIDCSubjectClaim at 6.
Out of scope, filed on LeanerCloud/cloud-commitments-platform#153
Three adjacent pre-existing gaps, all reproducible on origin/main and all deliberately left alone here: iacData is missing CUDlyAPIURL / ContactEmail / SourceAccountID / OIDCIssuerHost, so every .tfvars path of this script currently fails to render; shellEscape does not escape }, which matters for the ${VAR:-<value>} interpolation contexts; and two server-side render paths (azure-wif-bicep-deploy.sh.tmpl, the .auto.tfvars templates) emit shell and HCL from unescaped data. Details and reproductions in https://github.com/LeanerCloud/CUDly/issues/1690#issuecomment-5168468307.
Not merging; leaving that to a human as usual.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
internal/iacfiles/templates/README.md (1)
19-35: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winAdd
OIDCSubjectClaimto the template variables list.This table documents every field the templates receive.
scripts/generate-federation-iac.goaddsOIDCSubjectClaimtoiacData, and three templates (aws-cfn-deploy.sh.tmpl,aws-wif-cf-params.json.tmpl,aws-wif.tfvars.tmpl) now read it, but the table still omits it. A reader relying on this table to understand available template fields will miss the new one.📝 Proposed fix
OIDCIssuerURL — OIDC issuer URL (AWS target only) OIDCAudience — OIDC audience (AWS target only) +OIDCSubjectClaim — OIDC subject (sub) claim pinning the AWS trust policy (AWS target, non-AWS source only) SubscriptionID — Azure subscription ID (azure target only)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/iacfiles/templates/README.md` around lines 19 - 35, Add OIDCSubjectClaim to the Template variables list in the README, documenting its purpose and applicable target/source scope consistently with the existing OIDCIssuerURL and OIDCAudience entries.
🧹 Nitpick comments (2)
internal/iacfiles/templates_test.go (2)
478-522: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winSplit this test file to stay under the 500-line limit.
The file now exceeds 500 lines. Move the AWS WIF execution harness (
awsStubScript,runRenderedWIFScript) and its tests into a separate file in the same package, for exampletemplates_aws_wif_test.go.As per coding guidelines: "Follow Domain-Driven Design with bounded contexts, keep files under 500 lines, and use typed interfaces for public APIs."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/iacfiles/templates_test.go` around lines 478 - 522, Split internal/iacfiles/templates_test.go to keep it below 500 lines by moving the AWS WIF execution harness symbols awsStubScript and runRenderedWIFScript, along with their associated tests, into a new same-package test file such as templates_aws_wif_test.go. Preserve the existing test behavior and shared package-level helpers, leaving non-AWS template tests in templates_test.go.Source: Coding guidelines
304-323: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winFail the test when the context timeout kills the script.
If the 30-second timeout fires,
cmd.Runreturns an*exec.ExitErrorfor the signal kill.errors.Asmatches it, so the helper returns exit code -1 with zero recorded AWS calls. Every reject case then passes, because it only requires a non-zero exit and no AWS call. A hanging script would report success.Check
ctx.Err()after the run and fail explicitly.♻️ Proposed fix to detect timeout kills
var exitErr *exec.ExitError if err := cmd.Run(); err != nil && !errors.As(err, &exitErr) { t.Fatalf("run rendered script: %v (stderr: %s)", err, errBuf.String()) } + if ctx.Err() != nil { + t.Fatalf("rendered script did not finish before the timeout: %v (stderr: %s)", ctx.Err(), errBuf.String()) + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/iacfiles/templates_test.go` around lines 304 - 323, Update the command execution flow around cmd.Run to check ctx.Err() immediately after the run completes, and fail the test explicitly when the context has been canceled or timed out. Preserve the existing *exec.ExitError handling for ordinary non-zero script exits, but do not allow a timeout-killed script to be treated as a valid rejection.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@internal/iacfiles/templates/README.md`:
- Around line 19-35: Add OIDCSubjectClaim to the Template variables list in the
README, documenting its purpose and applicable target/source scope consistently
with the existing OIDCIssuerURL and OIDCAudience entries.
---
Nitpick comments:
In `@internal/iacfiles/templates_test.go`:
- Around line 478-522: Split internal/iacfiles/templates_test.go to keep it
below 500 lines by moving the AWS WIF execution harness symbols awsStubScript
and runRenderedWIFScript, along with their associated tests, into a new
same-package test file such as templates_aws_wif_test.go. Preserve the existing
test behavior and shared package-level helpers, leaving non-AWS template tests
in templates_test.go.
- Around line 304-323: Update the command execution flow around cmd.Run to check
ctx.Err() immediately after the run completes, and fail the test explicitly when
the context has been canceled or timed out. Preserve the existing
*exec.ExitError handling for ordinary non-zero script exits, but do not allow a
timeout-killed script to be treated as a valid rejection.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 47a335dc-35b6-40db-8699-73c23830f9da
📒 Files selected for processing (11)
internal/api/handler_federation.gointernal/api/handler_federation_test.gointernal/iacfiles/templates/README.mdinternal/iacfiles/templates/aws-cfn-deploy.sh.tmplinternal/iacfiles/templates/aws-wif-cf-params.json.tmplinternal/iacfiles/templates/aws-wif-cli.sh.tmplinternal/iacfiles/templates/aws-wif.tfvars.tmplinternal/iacfiles/templates_test.goknown_issues/13_iac_aws_target.mdscripts/generate-federation-iac.goscripts/generate_federation_iac_test.go
🚧 Files skipped from review as they are similar to previous changes (7)
- internal/api/handler_federation.go
- internal/iacfiles/templates/aws-wif-cf-params.json.tmpl
- internal/iacfiles/templates/aws-cfn-deploy.sh.tmpl
- known_issues/13_iac_aws_target.md
- internal/iacfiles/templates/aws-wif-cli.sh.tmpl
- internal/iacfiles/templates/aws-wif.tfvars.tmpl
- internal/api/handler_federation_test.go
Adversarial review — round 6 (final): clean, ship itVerdict: no actionable findings. This was the sixth and last round on this PR. Recording it here because the preceding five rounds materially changed the change and existed only in out-of-band messages — reviews that alter an outcome should leave a trace on the artifact. What the six rounds found
Zero findings across all six rounds were in the original defect. Every one was in explanatory prose describing which The root cause was not the prose. It was the quantifier. Each attempt compressed three distinct combinations into one universal statement, and each correction fixed one combination while breaking another: round 3's "non-gcp source" correctly excluded Module-level verificationThe templates label
The labels are correct; the mechanism is one level below where the templates could show it. Rendering the templates would not have surfaced this — the difference between checking the artifact and checking the thing the artifact asserts. Quantifier sweepEvery universal or exclusive statement in the changed files was extracted and checked — 31 in total, including the CFN/TF The one that had been false in rounds 3, 4 and 5 — "each GCP target combination emits its own required pin" — is true only because it is now backed by exhaustive three-row enumeration rather than a quantifier. Divergence from the gcp-target module's own regex (intentional)
which deliberately permits Both are correct, because the sinks differ. In the Terraform module the value lands in a single-quoted CEL string literal and an IAM principal identifier, where Process noteNo edits or commits were made by this reviewer at any point across the six rounds. All changes were authored separately; this role was verification only. |
Closes #1640
PR #1602 made
OIDCSubjectClaima required CloudFormation parameter with nodefault, closing the subject-less AWS trust policy hole for the checked-in
template (
iac/federation/aws-target/cloudformation/template.yaml). Theinternal/iacfilesgenerator that produces the customer-facing bundle wasleft untouched at the time —
internal/was owned by concurrent in-flightbranches — so three bundle formats still shipped a subject-less policy or a
broken deploy.
Reachability
Established this concretely rather than inheriting the issue's framing (this
backlog has had p0s whose threat model turned out to be narrower than
claimed). It is not narrower here — for
target=aws, source=gcp(theCLI bundle's most common shape), the pre-fix trust policy without
:subis:{"StringEquals": {"accounts.google.com:aud": "sts.amazonaws.com"}}accounts.google.comis GCP's own identity-token issuer, used broadly by anyGCP customer's service account requesting an ID token with a custom audience
(
gcloud auth print-identity-token --audiences=sts.amazonaws.comis astandard, documented GCP→AWS federation pattern, not something specific to
CUDly). Without
:sub, this condition alone is satisfied by any GCP serviceaccount anywhere that mints a token with that audience — an unauthenticated-
in-practice bypass, exactly as severe as the CloudFormation hole #1543
already established. For
target=aws, source=azure, the bypass is scoped towhichever Azure tenant ends up in
OIDC_ISSUER_URL(the generic self-servicerender leaves a
<AZURE_TENANT_ID>placeholder for the operator to fill in),matching the same shape the CloudFormation template had before #1543 — still
a real bypass for every identity in that tenant, not narrower.
Gaps closed
aws-wif-cli.sh.tmpl(the exploitable one) — documentedOIDC_SUBJECT_CLAIMas "Optional" and built a trust policy with only the:audcondition when it was unset.format=cliis a first-classuser-selectable download that never goes through CloudFormation, so
nothing else in the pipeline rejected this. Fixed by dropping the
subject-less
elsebranch entirely and validatingOIDC_SUBJECT_CLAIM(non-empty, no whitespace/
$/*— the same characters PR sec(iac/aws): require OIDC subject claim in aws-target CloudFormation #1602 rejectsin the CloudFormation parameter, for the same IAM-policy-variable-expansion
reason) before any
awsCLI call, so a misconfigured run fails loudinstead of leaving a partially-configured OIDC provider behind.
aws-cfn-deploy.sh.tmpl/buildCFParamsJSON/aws-wif-cf-params.json.tmpl— never forwarded
OIDCSubjectClaim, so the CFN deploy already failed atchange-set creation with
Parameters: [OIDCSubjectClaim] must have valuesonce sec(iac/aws): require OIDC subject claim in aws-target CloudFormation #1602 made the parameter required. Fixed by threading a new
federationIaCData.OIDCSubjectClaimfield through all three.aws-wif.tfvars.tmpl— emittedoidc_subject_claimcommented out andlabelled "Optional", contradicting the Terraform module's required,
no-default variable. Fixed: emitted uncommented, "Optional" label removed.
federationIaCData.OIDCSubjectClaimstays empty from every generic-bundlebuilder (
buildGenericIaCData) by design: unlikeOIDCIssuerURL/OIDCAudience, which are derivable fromtarget/sourcealone, CUDly'sserver has no generic way to know the calling workload's real subject claim.
Every artifact now requires it explicitly (fails loud / prompts / rejects
empty at deploy-or-run time) instead of defaulting to a
working-but-insecure empty value — the same "generic bundle, filled in by the
operator at apply time" pattern this codebase already uses for
OIDCSubjectClaimin the CloudFormation and Terraform paths.The standalone
scripts/generate-federation-iac.gomirror (explicitlydocumented as needing to stay in sync with
internal/iacfiles/templates/)gains the same field plus an
--oidc-subject-claimflag.What I deliberately did NOT fix here (filed separately)
aws-wif-cli.sh.tmplalso hardcodes an unoverridable all-zerosOIDC-provider thumbprint placeholder, and the provider-exists branch skips
re-checking it on re-run. This is the CLI-bundle sibling of sec(iac/aws): aws-target CloudFormation accepts the all-zeros OIDC thumbprint for any issuer #1615, which PR
sec(iac/aws): reject the all-zeros OIDC thumbprint in the aws-target bundles #1678 fixed for the CloudFormation/Terraform bundles but deliberately left
this file alone (noted on sec(iac): federation bundle generator still emits a subject-less AWS trust policy (CLI bundle exploitable) #1640 by the sec(iac/aws): reject the all-zeros OIDC thumbprint in the aws-target bundles #1678 author, since
internal/iacfiles/was this issue's scope, not sec(iac/aws): aws-target CloudFormation accepts the all-zeros OIDC thumbprint for any issuer #1615's). Not anauthentication bypass — AWS only consults the configured thumbprint on a
fallback path, and all-zeros matches nothing there, so the failure mode is
availability/misconfiguration, not takeover. Filed as its own low-severity
issue rather than folded into this PR since it's a distinct defect with a
distinct (non-security) fix shape.
generate-federation-iac.goscript isindependently broken for
--target aws --format tfvars|bundleonmaintoday:
iacDatais missingCUDlyAPIURL,ContactEmail, andOIDCIssuerHost, which the templates it renders already reference,producing a
text/templateexecution error. Confirmed this predates mychange (reproduced against
origin/main's copy of the script). Unrelatedto the subject-claim gap; a dev-tooling issue, not security. Filed
separately rather than widening this PR's scope.
Verification
bash -nandshellcheck0.11.0 on the renderedaws-wif-cli.sh.tmplandaws-cfn-deploy.sh.tmpl(Go templates rendered with sample data first,since
{{...}}isn't valid bash) — both exit 0, no findings.post-fix (reverted the relevant files to
origin/mainand re-ran):internal/iacfiles/templates_test.go:TestAWSWIFCLI_SubjectClaimRequired— asserts the rendered CLI scripthas exactly one
:subcondition (never zero), contains no subject-lessStringEqualsblock, rejects an emptyOIDC_SUBJECT_CLAIMbefore thefirst
awscall, and rejects whitespace/$/*.internal/api/handler_federation_test.go:TestGetFederationIaC_AWSWIF_SubjectClaimThreaded— asserts the CFNparams JSON, CFN deploy script, and bundle tfvars all carry
OIDCSubjectClaim/oidc_subject_claimexplicitly and uncommented.go build ./...andgo vet ./internal/api/... ./internal/iacfiles/...clean;
go test ./internal/api/... ./internal/iacfiles/...green.gofmt -lclean on all touched Go files.gosec, Trivy, markdown lint, etc.) — no
--no-verify.known_issues/13_iac_aws_target.mdupdated: theOIDCSubjectClaimentrymarked resolved with a description of the fix; a new entry added for the
thumbprint gap (#1689) so it isn't silently dropped from the doc.
Summary by CodeRabbit
New Features
Bug Fixes
Documentation