Chapter 13 of 16 · Application/workload user · orders-api

Kubernetes Authentication on EKS

Authenticate a pod with a projected service-account token bound to namespace, service account, audience, and lifetime.

Chapter contract

Persona: Application/workload user · orders-apiPhase: AWS and EKS workloadsEstimated time: 45 minutes

Prerequisites:

kubectl for optional client dry-run and a platform-supplied Kubernetes auth design; no cluster apply.

User-visible outcome:

An EKS pod identity is bounded by service account, namespace, audience, and token lifetime.

Learning objectives

Consumer flow

Projected SA tokenstep 1Token validationstep 2Vault K8s rolestep 3Pod Vault tokenstep 4

Ownership boundary

OwnerConsumer-facing responsibility
You ownStates the consumer contract and proves reload and degraded behavior.
Platform team ownsOwns runtime identity, integration components, rollout, and operational health.
Vault ownsOwns server-side trust, policy, engines, audit, and Vault service health.

Core concepts

Projected token

A bounded, expiring service-account JWT in a projected volume.

Audience

The intended verifier accepted by token request and Vault.

TokenReview

A Kubernetes API check validating a service-account token.

Role binding

Vault constraints on service-account names and namespaces.

Commands and configuration

kubectl -n lockbox create token orders-api   --audience=vault --duration=10m   --output=jsonpath='{.status.expirationTimestamp}'
kubectl -n lockbox get serviceaccount orders-api   -o jsonpath='{.metadata.name}{"\n"}'
vault read -format=json auth/kubernetes/role/orders-api   | jq '{service_accounts:.data.bound_service_account_names,namespaces:.data.bound_service_account_namespaces}'

Secret-safety stop

Stop: Do not print, decode, copy, or persist projected service-account tokens. Inspect requested audience and expiry through configuration metadata.

Failure drill

SymptomPod login gets invalid audience or service account not authorized.
Likely causesAudience, mount, namespace, service account, reviewer, issuer, or cluster trust mismatch.
Inspect safelyInspect projection, service account, namespace, role metadata, events, and time.
Do not printProjected JWT, TokenReview body, Vault token, pod environment, or secret volume.

Break it / fix it

Break it: Change the projected audience or service account.

Show diagnosis and fix

Fix it: Restore the platform-approved audience, namespace, service account, auth mount, and role bounds.

Escalate with time, endpoint, auth path, role, mount, namespace when relevant, status code, request ID, and sanitized error class. Never attach a credential or response body.

Try it

Bootstrap boundary

Platform-supplied external configuration is represented by reserved example inputs; this lab applies nothing.

Cost:

$0; offline validation with no external resource changes

Starting state:

Use the tracked example and offline validator; real GitLab, AWS, and Kubernetes configuration remains platform-owned.

User actions:

Statically validate the example objects without contacting a cluster.

cd learn-vault/labs/kubernetes-auth
python3 validate_manifests.py

Optional approved context: kubectl apply --dry-run=client -f service-account.yaml -f pod-projection.yaml creates nothing, but kubectl may still contact the current API server for discovery or schema validation.

Success criteria:

Complete every item in the Verify section using metadata-only evidence; no secret value appears in terminal output or tracked files.

Troubleshooting:

Use the Failure drill and Break it / fix it evidence fields. Stop before broadening policy, weakening identity or TLS checks, or copying secret-bearing diagnostics.

Verify

  1. A dedicated orders-api service account is in lockbox.
  2. Projection sets audience vault and finite expirationSeconds.
  3. Default service-account token automount is disabled.
Evidence rule: retain only status, policy names, TTLs, versions, timestamps, fingerprints, and error classes. Never retain secret values.

Cleanup

Client dry-run creates nothing. Delete only an explicitly created disposable namespace if you went beyond the course.

Project Lockbox increment

The EKS contract uses dedicated projected identity and exact namespace/service-account bounds; AWS permission remains separate.

Quick check

Is a pod SA token an AWS credential?

No. AWS exchange and Vault validation are separate trust paths.

Why set audience?

It narrows which verifier should accept the token.

Why disable default mounting?

The pod should receive only its explicit bounded projection.

What minimum role bounds apply?

Exact service account, namespace, policy, and TTL.

Gotchas

Recap and next

Kubernetes auth is strong when projected identity is bounded and the Vault role matches the exact workload.

Primary references

Continue →