close
Skip to content

fix(security): remove committed Apple Sign In private key from E2E config - #14986

Open
Simone319 wants to merge 1 commit into
devfrom
security/remove-committed-apple-key
Open

fix(security): remove committed Apple Sign In private key from E2E config#14986
Simone319 wants to merge 1 commit into
devfrom
security/remove-committed-apple-key

Conversation

@Simone319

Copy link
Copy Markdown
Contributor

The finding

Secret scanning (Mirador acat-bosco/rsa-private-key) flagged a committed private-key literal in
extract-apple-private-key.test.ts. On investigation, the value is not an inert placeholder —
it is a real, cryptographically valid P-256 (ES256) private key:

  • openssl pkey -inform DER parses it: ASN1 OID: prime256v1, NIST CURVE: P-256
  • A sign → verify round trip succeeds (Verified OK)
  • It was introduced in May 2021 with the Sign in with Apple feature (Sign in with Apple - add and update auth #7265), so it has been
    public for ~5 years, on both dev and main

An earlier triage of mine concluded the value was unparseable. That was wrong: it was tested with
openssl ec, which expects SEC1 format, while this key is PKCS#8 — the parse error was a format
mismatch, not invalid key material. Correcting that here.

Per the in-repo comments ("the following keys are invalidated but they pass Cognito validation")
the key was deliberately revoked Apple-side, which is plausible — but a code comment is not
verification, and valid key material should not sit in a public repo regardless.

Sites not covered by #14985

PR #14985 removes the literal from the one file Mirador flagged. The same key is committed at
9 further sites across 8 files, none of which were flagged (the 4-dash ----BEGIN markers
likely evade the scanner's regex — a detection gap worth fixing separately):

File Change
packages/amplify-e2e-core/src/utils/envVars.ts mock branch + getEnv fallback use a generated key
packages/amplify-e2e-core/src/utils/auth-utils.ts appleAppPrivateKey uses the same helper
packages/amplify-e2e-tests/sample.env distinct placeholders (also fixes a duplication bug)
codebuild_specs/run_e2e_tests_linux.yml drop hardcoded APPLE_PRIVATE_KEY_2
codebuild_specs/run_e2e_tests_linux_split.yml ditto
codebuild_specs/run_e2e_tests_windows.yml ditto
codebuild_specs/run_e2e_tests_windows_split.yml ditto
codebuild_specs/amplify_console_integration_tests.yml ditto

Approach: generate at run time — no CI secret required

No new CI secret needs to be configured. APPLE_APP_ID (com.fake.app), APPLE_TEAM_ID and
APPLE_KEY_ID are all fake values, and the committed key is revoked — yet these tests pass today.
That proves no Apple round trip occurs: Cognito only validates the key's structure when the
provider is configured. So no site needs a specific registered key, only a well-formed one.

Injecting a key from Secrets Manager was considered and rejected: it would add a manual setup step,
an IAM change and a CI-breakage window, and would still store key material — for no benefit, since
nothing depends on a particular key.

getEphemeralApplePrivateKey() (new, in envVars.ts) generates a memoized P-256 key and flattens
the PEM to a single line. The single-line form is required: callers type this value into
interactive CLI prompts via .send()/.sendLine(), so an embedded newline would register as an
Enter keypress and break the prompt. extractApplePrivateKey strips whitespace and is
delimiter-dash agnostic, so a single-line PEM parses correctly.

Escape hatch preserved: the getEnv branch still prefers an injected APPLE_PRIVATE_KEY_2 and only
falls back to the generated key when unset. Anyone who does want to pin a specific key can inject
one from Secrets Manager with no code change. The now-redundant APPLE_PRIVATE_KEY entry was also
dropped from missingVars, so removing the literal from the CodeBuild specs cannot fail a run.

APPLE_PRIVATE_KEY / _2 duplication

In sample.env these two were byte-identical, so any test expecting two distinct keys was
silently exercising the same one. They are now distinct placeholders, with a note that
getSocialProviders() reads only APPLE_PRIVATE_KEY_2.

Verification

  • tsc --noEmit --strict on envVars.ts: clean
  • prettier --check on all 7 TS/YAML files: All matched files use Prettier code style!
  • All 5 CodeBuild specs re-parse as valid YAML with APPLE_PRIVATE_KEY_2 absent
  • 17/17 functional checks pass against the transpiled real sources: single-line output, memoization,
    extractApplePrivateKey round trip yielding a 138-byte P-256 PKCS#8 body, idempotence, generated key
    validity (sign → verify), mock-branch fields intact, getEnv precedence (injected value wins),
    fallback when unset (no throw), and that genuinely missing vars still throw
  • Repo-wide grep confirms zero remaining occurrences of the key body other than the file test(amplify-category-auth): generate ephemeral EC key at runtime instead of committed key literal #14985 removes

Follow-up (not in this PR)

  1. Confirm the key is revoked for Apple team 2QLEWNDK6K / key 2QLZXKYJ8J; rotate if not.
  2. Fix scanner coverage for 4-dash defanged PEM markers — 9 of the 10 copies were never flagged.

…nfig

The Sign in with Apple private key committed across the E2E test configuration
is a real, cryptographically valid P-256 (ES256) key, not an inert placeholder:
`openssl pkey` parses it and a sign/verify round trip succeeds. Per the in-repo
comments it was deliberately invalidated Apple-side, but it has been public
since May 2021, so the literal should not remain in source.

None of these call sites need a specific registered key. APPLE_APP_ID
(com.fake.app), APPLE_TEAM_ID and APPLE_KEY_ID are all fake and the committed
key is revoked, yet the tests pass today - so no Apple round trip occurs and
Cognito only performs config-time structural validation. A key generated at run
time satisfies every site.

Add getEphemeralApplePrivateKey() to amplify-e2e-core/src/utils/envVars.ts,
which generates a memoized P-256 key and flattens it to a single line (callers
type this value into interactive CLI prompts, where a newline would register as
an Enter keypress).

- envVars.ts: mock branch uses the generated key; the getEnv branch prefers an
  injected APPLE_PRIVATE_KEY_2 and falls back to the generated key, so removing
  the literal from CI config cannot fail the run.
- auth-utils.ts: appleAppPrivateKey uses the same helper.
- sample.env: distinct placeholders for APPLE_PRIVATE_KEY and
  APPLE_PRIVATE_KEY_2, which were previously byte-identical, plus a note that
  only APPLE_PRIVATE_KEY_2 is read.
- codebuild_specs (5 files): drop the hardcoded APPLE_PRIVATE_KEY_2 value.

Test-only and CI-config-only; no runtime or customer code path is affected.
@Simone319
Simone319 requested a review from a team as a code owner September 10, 2026 15:17
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