docs/guides/auth-in-kubernetes/page.md
{% answer %}
GoFr supports Basic Auth, API key auth, and OAuth 2.0 JWT validation against a JWKS endpoint (EnableOAuth(jwksEndpoint, refreshInterval, options...)). In Kubernetes, point the JWKS URL at your IdP (cluster-internal Service or public URL), inject API keys via Vault Agent or sealed Secrets, and prefer mTLS or JWT over static keys for service-to-service calls.
{% /answer %}
Three authentication categories are exposed on the App, all verified in pkg/gofr/auth.go — Basic auth, API-key auth, and OAuth/JWT — each with a static-credentials variant and a custom-validator variant:
EnableBasicAuth(credentials...) — pairs of username/password.EnableBasicAuthWithValidator(fn) — custom validator with access to the container.EnableAPIKeyAuth(keys...) — X-Api-Key header check.EnableAPIKeyAuthWithValidator(fn) — custom validator.EnableOAuth(jwksEndpoint, refreshIntervalSeconds, options ...jwt.ParserOption) — JWT validation with periodic JWKS refresh.A single call enables auth on both HTTP and gRPC. The entire /.well-known/* prefix (including /.well-known/alive and /.well-known/health) is auth-exempt by default — see pkg/gofr/http/middleware/validate.go. Both endpoints are deliberately minimal, so the exemption does not expose anything sensitive.
For full code examples, see Authentication.
EnableOAuth registers an internal HTTP service named gofr_oauth to fetch keys, then validates JWTs on every request. Two deployment patterns:
app.EnableOAuth("https://your-tenant.auth0.com/.well-known/jwks.json", 3600,
jwt.WithAudience("https://api.example.com"),
jwt.WithIssuer("https://your-tenant.auth0.com/"),
jwt.WithExpirationRequired())
Egress from your cluster must be allowed to reach the IdP. If you have a strict NetworkPolicy, allowlist the IdP CIDR or use a forward proxy.
If your IdP runs in the same cluster, point at its in-cluster Service DNS:
app.EnableOAuth("http://keycloak.iam.svc.cluster.local:8080/realms/prod/protocol/openid-connect/certs", 3600)
The JWKS fetch is cheap, and the refreshInterval controls how stale your key cache can be. A typical value is 600–3600 seconds. After key rotation by the IdP, requests with old tokens fail until the cache refreshes.
EnableAPIKeyAuth takes the keys directly. In production, source them from a secret manager:
vault.hashicorp.com/agent-inject: "true" annotation and read with app.Config.Get.Avoid bundling API keys into ConfigMaps or container images.
For internal calls between GoFr services, three reasonable models:
PeerAuthentication: STRICT or Linkerd automatic mTLS. No GoFr code change needed. Strongest identity, requires mesh ops.EnableOAuth. Works without a mesh.Avoid mixing on a single endpoint. Pick one per trust boundary.
For OAuth, GoFr refreshes JWKS on the interval you pass. The receiving service does not refresh user tokens — that is the client's responsibility. For long-lived clients (cron jobs, batch workers), refresh ahead of expiry rather than on 401.
Once OAuth is enabled, ctx.GetAuthInfo().GetClaims() returns the parsed claim map. Cast specific claims as needed:
claims := ctx.GetAuthInfo().GetClaims()
userID, _ := claims["sub"].(string)
Kubernetes liveness probes fire from the kubelet without credentials. GoFr exempts /.well-known/alive from auth so probes succeed. Do not put auth in front of the alive endpoint via an Ingress filter.
/.well-known/health is exempted from auth by default so readiness probes reach it without credentials. Its body is limited to {"name", "status"} — the aggregate UP / DEGRADED roll-up, with no datasource hosts, names, or connection details — so an unauthenticated caller cannot enumerate your backends from it.
Always serve credentials and tokens over TLS. Inside the cluster, the mesh (or CERT_FILE / KEY_FILE configured directly on GoFr) terminates TLS; on the edge, the Ingress does.
{% faq %}
{% faq-item question="Can I run JWKS-based JWT auth without a service mesh?" %}
Yes. EnableOAuth just needs an HTTP-reachable JWKS endpoint. The mesh is optional and adds mTLS at the network layer.
{% /faq-item %}
{% faq-item question="Where should API keys be stored?" %}
In a secret manager (Vault, AWS/GCP Secrets Manager) and surfaced to the pod as environment variables via Vault Agent or External Secrets Operator. Never in ConfigMaps or container images.
{% /faq-item %}
{% faq-item question="Does enabling auth in GoFr also protect gRPC?" %}
Yes. A single call to EnableBasicAuth, EnableAPIKeyAuth, or EnableOAuth registers middleware on both the HTTP and gRPC servers — verified in pkg/gofr/auth.go.
{% /faq-item %}
{% /faq %}