Skip to content

Authentication and Token Lifecycle

Aidin SDK utilizes a secure, zero-trust token exchange mechanism. Developers authenticate once using their Authentik identity, which the SDK exchanges for a short-lived Kubernetes ServiceAccount token specifically scoped to their project namespace.


The complete authentication and authorization lifecycle proceeds through three stages:

[Developer / CLI]
|
| 1. Upstream Authentik Bearer Token (in-memory only)
v
[Aidin Token Exchanger] (https://token-exchanger.<AIDIN_BASE_URL>)
|
| 2. Validates identity & verifies project membership in Kubernetes RBAC
| 3. Requests TokenRequest from Kubernetes API (scoped to project namespace)
v
[Kubernetes API Server]
|
| 4. Returns short-lived SA token + RFC3339 expiration timestamp
v
[Aidin Token Exchanger]
|
| 5. Returns JSON { token, namespace, expires_at }
v
[Aidin SDK Client]
|
| 6. Securely caches service token (~/.aidin/<project>/token.json mode 0600)
v
[Aidin Pipelines API] (https://pipeline-server.<AIDIN_BASE_URL>)
  1. Upstream Credential: The user supplies an Authentik bearer token via the AUTHENTIK_TOKEN environment variable, standard input (--token-stdin), or the -t CLI flag.
  2. Token Exchange: The SDK transmits the upstream token over TLS to https://token-exchanger.<AIDIN_BASE_URL>/exchange with the target project_name.
  3. Cluster Token Minting: The Token Exchanger verifies the user’s group memberships and calls the Kubernetes TokenRequest API to mint a short-lived ServiceAccount token bounded to the project’s namespace.
  4. Credential Packaging: The response payload includes:
    • token: The minted Kubernetes ServiceAccount JWT.
    • namespace: The target Aidin project namespace.
    • expires_at: Strict ISO-8601 / RFC3339 UTC timestamp indicating token expiration.
  5. Secure Persistence: The SDK caches the minted token and metadata locally under the project directory.

Token validation in the Aidin SDK follows strict security rules:

Network latency and host clock drifts can cause tokens to expire during an in-flight request. The SDK applies a safety margin:

effective_expiration = expires_at - 60 seconds

Whenever a cached token is evaluated, if current_time + 60s >= expires_at, the token is deemed expired immediately, prompting re-authentication.

Earlier authentication systems attempted to test credentials by calling general /health or status endpoints. In Aidin SDK 0.4.0:

[!CAUTION] Health endpoints (GET /health) are unauthenticated ping routes and do not validate credentials. The Aidin SDK never treats a successful health check as proof of token validity. Expiration is enforced solely using cryptographic timestamps provided by Kubernetes TokenRequest.

If a cached token does not contain a verifiable expires_at timestamp, the SDK refuses to load it and demands re-authentication.


Local credentials must remain shielded against multi-user hosts and malicious local processes.

~/.aidin/
├── <project-a>/
│ └── token.json (Mode: 0600 / -rw-------)
└── <project-b>/
└── token.json (Mode: 0600 / -rw-------)

1. In-Memory Only for Upstream Credentials

Section titled “1. In-Memory Only for Upstream Credentials”

Upstream Authentik tokens are never written to disk. They exist only in process memory during the exchange request and are promptly garbage collected.

  • Directory permissions: Cache directories are created with mode 0700 (drwx------).
  • File permissions: Credential files (token.json) are written with mode 0600 (-rw-------).
  • Enforcement on Read: If a cached token file has group or world read/write permissions (mode & 0o077 != 0), the SDK refuses to read it and throws a CredentialStorageError.

The credential loader explicitly verifies that token.json is not a symbolic link. If a symlink is detected, the SDK raises an exception immediately to prevent arbitrary file reading attacks.

Credential writing uses temporary files (tempfile.NamedTemporaryFile) within the same directory followed by an atomic os.replace operation. This prevents file corruption and race conditions during concurrent processes.

To prevent tokens from being accidentally reused when switching Authentik identities for the same project, the cache records an identity_hint (the first 16 characters of the SHA-256 digest of the upstream token). If an upstream token is provided and does not match the stored hint, the cache is invalidated.


The cached JSON stored in ~/.aidin/<project>/token.json adheres to the following structure:

{
"version": 2,
"token_type": "kubernetes-service-account",
"project_name": "marketing-analytics",
"namespace": "marketing-analytics",
"exchanger_url": "https://token-exchanger.platform.aidin-ai.com",
"token": "eyJhbGciOiJSUzI1NiIsImtpZCI6...",
"expires_at": "2026-11-09T09:45:00+00:00",
"obtained_at": "2026-11-09T08:45:00+00:00",
"identity_hint": "9f83c6b12a87c4d5"
}

To invalidate the local session and remove stored credentials for a project:

Terminal window
aidin logout -p my-project
  • Running aidin logout immediately purges token.json and legacy token caches from your workstation.
  • Because Kubernetes ServiceAccount tokens are stateless JWTs, previously issued tokens remain technically valid on the cluster until their expiration timestamp (expires_at), unless revoked centrally by platform administrators.
  • If re-authentication is required prior to expiration, use aidin login -p <project> --force-refresh.