Skip to content

fix(iam): random access key secrets and STS credentials - #1437

Merged
NitinKumar004 merged 3 commits into
developmentfrom
fix/iam-random-secret-keys
Oct 4, 2026
Merged

NitinKumar004 merged 3 commits into
developmentfrom
fix/iam-random-secret-keys

Conversation

@NitinKumar004

Copy link
Copy Markdown
Collaborator

Summary

IAM CreateAccessKey built secrets as secret-%08x from the shared id counter. Under serve --enforce-auth, anyone who knew an access key id could guess the secret in a few tries and forge SigV4 requests. A test that signs with secret-00000010 against a fresh key got a 200 on the old code.

Changes

  • internal/idgen: new SecretAccessKey (40 chars, base64 alphabet), SessionToken (356 chars, base64 alphabet) and OCIAuthToken (20 chars). They use crypto/rand with rejection sampling and return an error rather than falling back to a fixed value.
  • AWS IAM CreateAccessKey now uses the random secret and retries the key id on collision.
  • STS SessionStore.Mint now issues ASIA + 16 base32 ids, 40-char secrets and a long random session token. Ids are unique within the store.
  • Auth gate: an ASIA credential is only accepted with the session token STS issued for it, taken from the X-Amz-Security-Token header or query parameter. Before this, the token was never checked.
  • Azure/GCP IAM access key secrets and OCI auth tokens were also counter-based. They now use the same random generators.

Not changed

  • Auth-off mode is unchanged. STS still returns its fixed synthetic credentials and any credentials (test/test) are accepted.
  • Snapshots already store secrets verbatim, so restored keys keep their secrets. Keys created after a restore are random.
  • Seed fixtures, compat, contrib and docs don't hard-code generated secrets, so no deterministic mode was needed.

Testing

  • New tests failed on the old code and pass now: secret shape and charset, no two keys share a secret, a secret is not derivable from the counter, the counter-guess forgery gets 403 under EnforceAuth, ASIA requires its session token, and the STS credential shape.
  • go test -race on internal/idgen, providers/{aws,azure,gcp}/iam, providers/oci/..., server/aws/..., server/wire/sigv4, server/wire/awsidentity, persist, seed, server/oci, compat/aws auth tests and contrib/server EnforceAuth.
  • golangci-lint (new-from-rev) clean. coveragegen produced no diff.
  • E2E against cloudemu serve --enforce-auth with the aws CLI:
    • A bootstrap key minted on an auth-off server and restored by snapshot signs requests.
    • A new user's key signs requests.
    • 64 counter-guessed secrets are all rejected.
    • AssumeRole credentials work, and fail without the token or with a guessed secret.
    • After snapshot, reset and restore, the old key still works and new keys are random.

IAM secrets were secret-%08x off the shared id counter, so anyone who knew a
key id could guess the secret and forge SigV4 under --enforce-auth. Secrets
are now 40 random base64 chars; STS uses ASIA + base32 ids and a long random
session token, and the gate now requires that token with ASIA keys. Azure and
GCP access keys and OCI auth tokens get the same treatment.
…-secret-keys

# Conflicts:
#	server/aws/authgate.go
…etries

randString no longer falls back to all-A ids, and every caller passes the
error up. Access key id collision retries in IAM and STS stop after 5 tries
with an internal error.
@NitinKumar004
NitinKumar004 marked this pull request as ready for review October 4, 2026 09:57
@NitinKumar004
NitinKumar004 merged commit 7d290fd into development Oct 4, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant