Blog
dev
6 min read

The Moment You Hardcode Keys, Authentication Collapses: Token Design to Prevent Signing Key Incidents

When signing keys are tied to "deployables," resignation, leaks, and recovery failures directly lead to authentication collapse. Build a rotation-capable structure with JWKS + kid-based verification, and remember JWT validation includes not just signatures but iss/aud/exp/alg as well.

One-sentence conclusion: When signing keys are tied to "deployables," resignation, leaks, and recovery failures directly lead to authentication collapse.

In token-based authentication, the "signing key" is the root of trust. If this key is exposed or not revoked, attackers can create tokens that look legitimate and pass through the system.

The problem isn't the algorithm—it's operations. Without a structure that allows key rotation/revocation/tracking, authentication cannot be sustained.

This article starts from key issues mentioned in reports (hardcoded signing keys, difficult key renewal, abandoned keys from resigned employees, and the "even viewing is a leak" controversy), and organizes signing key operations + token verification architecture in a reproducible format for Next.js-based services.


Background/Problem

The structural problems revealed in reports fall into two categories:

  1. Signing keys were hardcoded in source code, making key changes cumbersome as "code modification + redeployment."
  2. The gateway simply passed tokens if signing keys matched—a simple structure where compromised "legitimate" keys allowed forged tokens through.

Another important point: contrary to claims of "only viewing without saving," the government interpreted unauthorized viewing itself as 'leakage' when it escapes control.


Core Concepts

The goal of signing key operations is not "secure storage" but "easy rotation"

Secure key storage is basic. But the decisive factor preventing incidents is Key Rotation. When keys leak, they must be "changed immediately," and old keys must be "revoked without exception." If this process is slow or cumbersome, security collapses in practice.

As shown in the diagram below, separating "key storage" from "validation points" and making rotation natural through key identifiers (kid) dramatically reduces operational difficulty.

다이어그램 불러오는 중...

Expected outcome/What changed: Even when keys change, validation follows "without redeployment," and operational paths emerge that allow immediate key rotation when resignation/leak issues arise.

Reference: Token (JWT) structure and JWK/JWKS are standardized. (RFC 7519 JWT, RFC 7517 JWK, RFC 8725 JWT Best Practices)


Solution Approach

Approach 1) Separate signing keys from code and make rotation the default

  • Keys must never be included in source code/repositories/client bundles.
  • Issuance servers load keys from key storage for signing; validation servers verify using public keys (JWKS).
  • Key rotation isn't an "annual event" but becomes the default action for incident response, automated.

The strongest practical criterion: "If key changes are difficult, you'll eventually postpone them." Lower operational costs to maintain security.

Approach 2) Make gateway validation about "validation rules," not "key matching"

JWT validation doesn't end with correct signatures. At minimum, fix the following:

JWT Validation Checklist
  • Restrict allowed algorithms (prevent alg confusion)
  • Validate issuer (iss), audience (aud)
  • Validate expiration (exp), issuance (iat), short TTL
  • kid-based key selection + JWKS cache (short TTL) + immediate reflection on key revocation
  • Token revocation/blocking (blacklist) or introspection (server confirmation) as needed
  • OWASP has well-organized recommended checklists. (OWASP JWT Cheat Sheet)

    Approach 3) Treat "resigned employee access" as a permission/audit issue, not just a key issue

    Even with key rotation, if internal accounts/permissions/audit (logs) are lax, the same incidents repeat.

    • Resignation/transfer events automatically connect to immediate permission revocation
    • Separate service account keys/tokens from human accounts and keep lifespans (TTL) short
    • Treat viewing as data access; apply separate alerts/rate limits/session risk scoring to sensitive queries

    Implementation (Code)

    The example below shows the basic pattern for verifying JWT in Next.js (Route Handler), fetching keys via JWKS and selecting by kid. (Choose libraries per team policy, but the core is "don't hardcode keys in code.")

    1) Server-side JWKS Validation

    app/api/protected/route.ts

    typescript
    import { NextResponse } from "next/server";
    
    // Example: In practice, use validation libraries (JWK/JWKS + kid support)
    // This code is a skeleton to show "structure."
    
    async function fetchJwks() {
      const res = await fetch(process.env.JWKS_URL!, { cache: "no-store" });
      if (!res.ok) throw new Error("JWKS fetch failed");
      return res.json();
    }
    
    export async function GET(req: Request) {
      const auth = req.headers.get("authorization");
      const token = auth?.startsWith("Bearer ") ? auth.slice(7) : null;
      if (!token) return NextResponse.json({ ok: false }, { status: 401 });
    
      // 1) Extract kid from header
      // 2) Select public key matching kid from JWKS
      // 3) Verify signature/iss/aud/exp, etc.
      // (Delegating implementation details to libraries is safer.)
    
      const jwks = await fetchJwks();
    
      // TODO: verify(token, { jwks, issuer, audience, algorithms })
      // const payload = ...
    
      return NextResponse.json({ ok: true });
    }

    Expected outcome/What changed: Validation servers verify with rotating keys following JWKS, not "hardcoded single keys." Key replacements immediately reflect in validation.

    2) Keep Operational Checklists Next to Code (Pre-deployment Gate)

    markdown
    - [ ] Signing keys/secrets are not included in source code/environment output/client bundles
    - [ ] JWT validation fixes iss/aud/exp/alg
    - [ ] JWKS cache TTL and key rotation policy are documented
    - [ ] Resignation/permission change events immediately connect to access revocation
    - [ ] Sensitive queries have logging/alerts/rate limits applied

    Expected outcome/What changed: "What we must protect" gets repeatedly validated during PR/release processes, reducing operational omissions.


    Validation Method (Checklist)

    Key rotation is possible without "code modification/redeployment"
    JWKS-based kid is used, and revoked keys are immediately reflected
    JWT validation applies all iss/aud/exp/alg restrictions
    Resignation/permission changes automatically trigger access revocation
    "Viewing" is treated as data access with audit logs/alerts recorded

    Common Mistakes/FAQ

    Q1. Isn't extracting to environment variables not hardcoding?

    Environment variables are better than "embedding in code," but they can leak through deployment pipelines/logs/dumps. The core is "not copying secrets into the application," and must include rotation/audit in operations.

    Q2. Isn't a token valid if the signature is correct?

    Signatures are only a necessary condition. Without validation rules like issuer/audience/expiration/allowed algorithms, it opens directly to attackers with "legitimate keys."

    Q3. Isn't it not a leak if it's just "viewing screens"?

    According to reports, the government explained that "viewing by unauthorized persons exposing data outside control is leakage." In product design, it's safer to treat access itself as an incident regardless of storage.


    Summary (3-5 lines)

    • Tying signing keys to code slows rotation, and authentication collapses at that moment.
    • Build a "rotation-capable structure" first with JWKS + kid-based validation.
    • JWT is a complete set including iss/aud/exp/alg validation, not just signatures.
    • 'Viewing' is data access, requiring audit/alert/permission revocation automation.

    Conclusion

    More important than securely "hiding" keys is operations that easily change, firmly revoke, and leave traces of keys.

    Eliminating signing key hardcoding and introducing JWKS-based rotation can break the structure where resignation, leaks, and recovery failures directly lead to authentication collapse.


    Related Posts