Universal Auth
Machine Identity authentication for service-to-KMS communication
Universal Auth
Universal Auth is the authentication method used by Hanzo services to access secrets in KMS. It uses Machine Identities — non-human credentials designed for automated service-to-service communication.
How It Works
┌──────────────┐ clientId + clientSecret ┌──────────────┐
│ Service │ ──────────────────────────────▶ │ KMS API │
│ (Pod) │ │ │
│ │ ◀────────────────────────────── │ │
│ │ access_token (JWT) │ │
│ │ │ │
│ │ Bearer <access_token> │ │
│ │ ──────────────────────────────▶ │ │
│ │ │ │
│ │ ◀────────────────────────────── │ │
│ │ { secrets } │ │
└──────────────┘ └──────────────┘- The kms-operator (or service SDK) presents
clientId+clientSecretto KMS - KMS validates credentials against the Machine Identity record
- KMS returns a short-lived JWT access token
- The token is used to fetch secrets from the authorized project/environment/path
- The token is refreshed automatically before expiry
Machine Identity Types
Shared Identity (Most Services)
A single Machine Identity is shared across all standard services. Each service is scoped to its own path via the KMSSecret CRD's secretsPath field.
# K8s Secret holding the shared credentials
apiVersion: v1
kind: Secret
metadata:
name: universal-auth-credentials
namespace: hanzo
type: Opaque
stringData:
clientId: "<machine-identity-client-id>"
clientSecret: "<machine-identity-client-secret>"Access scope: the shared services org, production environment, all paths.
Dedicated Identity (IAM)
IAM has its own Machine Identity (iam-service) to isolate its secrets in a separate KMS project.
apiVersion: v1
kind: Secret
metadata:
name: iam-kms-auth
namespace: hanzo
type: Opaque
stringData:
clientId: "<iam-machine-identity-client-id>"
clientSecret: "<iam-machine-identity-client-secret>"Access scope: hanzo-iam project, prod environment, all paths.
Creating a Machine Identity
Via KMS UI
- Navigate to kms.hanzo.ai → Organization Settings → Machine Identities
- Click Create Identity
- Set a descriptive name (e.g.,
my-service) - Under Authentication, enable Universal Auth
- Copy the generated
clientIdandclientSecret - Under Projects, grant access to the appropriate project with the required role (typically Viewer for read-only)
Via Hanzo IAM
A machine identity is a client-credentials application in Hanzo IAM. Register it (which mints a clientId/clientSecret), then grant it read access to the appropriate KMS org. The credentials are what your workload exchanges for a token.
Exchange credentials for a token
Once you have a clientId/clientSecret, log in to KMS:
curl -X POST https://kms.hanzo.ai/v1/kms/auth/login \
-H "Content-Type: application/json" \
-d "{\"clientId\":\"$KMS_CLIENT_ID\",\"clientSecret\":\"$KMS_CLIENT_SECRET\"}"{ "accessToken": "<JWT>", "expiresIn": 86400, "tokenType": "Bearer" }Use the returned accessToken as Authorization: Bearer <accessToken> on every secret read.
Storing Credentials in K8s
After creating the Machine Identity, store the credentials as a K8s Secret:
kubectl create secret generic my-service-kms-auth \
--namespace hanzo \
--from-literal=clientId="<client-id>" \
--from-literal=clientSecret="<client-secret>"Then reference it in your KMSSecret CRD:
spec:
authentication:
universalAuth:
credentialsRef:
secretName: my-service-kms-auth
secretNamespace: hanzoToken Lifecycle
| Property | Value |
|---|---|
| Token type | JWT |
| Default TTL | 86400 seconds (24 hours) |
| Max TTL | Configurable per identity |
| Refresh | Automatic by kms-operator |
| Revocation | Delete the Machine Identity or its Universal Auth config |
Access Control
Machine Identities support fine-grained access control:
| Role | Capabilities |
|---|---|
| Viewer | Read secrets |
| Developer | Read/write secrets |
| Admin | Full project access including member management |
| No Access | Explicitly deny (overrides inherited permissions) |
Access is scoped per-project. A single identity can have different roles on different projects.
Next Steps
Complete CRD reference
Full service inventory and patterns
How is this guide?
Last updated on