Core Concepts Explained¶
This section introduces key terms and architectural concepts used throughout the access control design. If you are new to distributed systems or Kubernetes-based platforms, this will help you build intuition before diving deeper into implementation details.
JWT Token¶
A JWT (JSON Web Token) is a compact, self-contained way to represent identity and authorization data.
In simple terms, it is a signed piece of data that says:
“This user is authenticated, and here is what they are allowed to do.”
A JWT typically contains:
- a subject (who the user is),
- claims (email, roles, groups),
- an expiration time,
- a cryptographic signature to prevent tampering.
In many systems, JWTs are passed from the browser to APIs with every request. However, in this platform, the JWT is never exposed to the browser. Instead, it is stored securely on the server and accessed only when needed.
Why JWTs are powerful
JWTs allow services to verify identity without calling the identity provider every time. This makes them efficient but also sensitive — which is why we keep them server-side.
mTLS (Mutual TLS)¶
mTLS (Mutual Transport Layer Security) is a way for two services to securely talk to each other while verifying each other's identity.
In standard HTTPS, only the server proves who it is. With mTLS, both sides prove their identity using certificates.
This means:
- Service A knows it is really talking to Service B,
- Service B knows it is really talking to Service A.
In the context of this architecture, mTLS is used inside the cluster to ensure that only trusted services can call sensitive internal endpoints.
Think of mTLS like ID badges
Every service has an identity badge (certificate). Communication only happens if both sides show valid badges.
HTTP-Only Authentication¶
HTTP-only authentication refers to a pattern where authentication data is stored in cookies that cannot be accessed by frontend JavaScript.
In this system, the browser receives a session_id stored in an HttpOnly cookie. This cookie is automatically sent with every request to the backend, but cannot be read or modified by client-side code.
This creates a very important safety boundary.
Instead of the frontend managing tokens directly, the browser simply carries the session along with each request, and the backend resolves it.
Why this matters
Even if malicious JavaScript runs in the browser, it cannot read the session cookie. This significantly reduces the risk of token leakage through XSS attacks.
How it feels in practice¶
From a developer’s perspective, authentication becomes almost invisible. You do not attach headers manually. You do not store tokens in local storage. The browser handles the session automatically. The backend remains the source of truth.
OAuth Token Exchange¶
OAuth token exchange is a mechanism where one token is exchanged for another, usually with a different scope or audience.
In this architecture, the idea of token exchange appears in a slightly adapted form.
Instead of exchanging one JWT for another JWT, the system exchanges a session identifier for a JWT + claims.
Why not give the JWT directly?
Because the session is safer to expose to the browser. The JWT is only revealed to trusted internal services.
North-South vs East-West Traffic¶
These terms describe how traffic flows in a system.
North-South traffic¶
This is traffic that comes from outside the cluster into the system, or leaves it.
Examples include a user accessing the frontend from a browser, or an external API calls coming through a load balancer. This traffic is typically: exposed through gateways or load balancers, more strictly controlled, and subject to authentication and rate limiting.
East-West traffic¶
This is traffic inside the cluster, between services.
Examples include internal communication between backend components.
This traffic is not exposed publicly and often secured with mTLS.
Why this distinction matters
The session exchange endpoint is East-West only. It must never be accessible via North-South traffic.
FE–BFF Pattern in Kubernetes¶
The Frontend–Backend-for-Frontend (FE–BFF) pattern is a design approach where the frontend does not talk directly to backend services. Instead, it communicates through a dedicated backend layer tailored to its needs.
What the BFF does¶
The BFF acts as a bridge between the frontend and the internal system. It handles authentication, manages sessions, aggregates and reshapes data, communicates with internal services.
Why this pattern is used here¶
In this platform, the BFF is critical because it:
- prevents JWT exposure to the browser,
- centralizes authentication logic,
- enforces consistent access control,
- simplifies frontend development.
How it fits into Kubernetes¶
In Kubernetes, the FE and BFF are typically deployed as separate services:
- the FE is often served as static content or via a web server,
- the BFF runs as a backend service within the cluster.
Traffic flows like this:
- the user enters through a load balancer (North-South),
- requests reach the BFF,
- the BFF communicates internally (East-West) with other services.
Why this matters for access control
The BFF becomes the only public entry point for authentication logic. All sensitive operations stay inside the cluster.
Envoy Proxy¶
Envoy is a high-performance proxy that sits in front of services and manages network traffic.
In a Kubernetes environment, Envoy is often deployed as a sidecar alongside each service. It handles:
- routing requests,
- enforcing security policies,
- collecting telemetry,
- managing retries and timeouts.
In this system, Envoy can play a key role in:
- controlling access to internal endpoints,
- enforcing mTLS,
- ensuring only allowed services can perform token exchange.
Envoy is planned for future use
Our service talks normally over HTTP. Envoy transparently intercepts and manages the traffic.
Keycloak¶
Keycloak is the identity provider used in this system.
It is responsible for:
- authenticating users,
- issuing JWTs,
- managing users, roles, and groups,
- supporting OAuth and OpenID Connect flows.
When a user logs in, the backend communicates with Keycloak to validate credentials. If successful, Keycloak returns a JWT that represents the user’s identity.
In this platform, Keycloak is never called directly from the frontend. All communication goes through the backend.
Keycloak is the source of truth
If you need to understand identity, roles, or claims — they originate from Keycloak.
How it fits into the flow¶
The BFF acts as a client of Keycloak. It performs authentication on behalf of the user and then stores the resulting JWT securely. This keeps the identity provider integration centralized and controlled.
PocketBase¶
PocketBase appears in the architecture as an internal service that needs authenticated access to user data.
It is a lightweight backend system that typically provides data storage, APIs and real-time capabilities.
In this design, PocketBase does not authenticate users directly through the browser. Instead, it relies on the platform’s access control system.
When PocketBase needs to act on behalf of a user, it:
- receives or uses a
session_id, - calls the internal session exchange endpoint,
- obtains the JWT and user claims,
- performs operations using that identity.
Why this matters¶
This approach ensures consistency across services.
Instead of each service implementing its own authentication logic, everything flows through the same mechanism:
login → session → internal exchange → JWT
What this avoids
PocketBase does not need to validate passwords or talk to Keycloak directly. It trusts the platform’s access control layer.