Hanzo

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 }                  │              │
└──────────────┘                                 └──────────────┘
  1. The kms-operator (or service SDK) presents clientId + clientSecret to KMS
  2. KMS validates credentials against the Machine Identity record
  3. KMS returns a short-lived JWT access token
  4. The token is used to fetch secrets from the authorized project/environment/path
  5. 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

  1. Navigate to kms.hanzo.aiOrganization SettingsMachine Identities
  2. Click Create Identity
  3. Set a descriptive name (e.g., my-service)
  4. Under Authentication, enable Universal Auth
  5. Copy the generated clientId and clientSecret
  6. 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: hanzo

Token Lifecycle

PropertyValue
Token typeJWT
Default TTL86400 seconds (24 hours)
Max TTLConfigurable per identity
RefreshAutomatic by kms-operator
RevocationDelete the Machine Identity or its Universal Auth config

Access Control

Machine Identities support fine-grained access control:

RoleCapabilities
ViewerRead secrets
DeveloperRead/write secrets
AdminFull project access including member management
No AccessExplicitly 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

On this page