NautheraServiceAccount
A NautheraServiceAccount resource provisions OAuth2 client credentials for machine-to-machine (M2M) authentication. Unlike an OidcClient, a NautheraServiceAccount has no redirect URIs, no login flow, and no consent screen — it exclusively uses the client_credentials grant type.
When you create a NautheraServiceAccount, the operator automatically generates a client_id and client_secret and projects them into a Kubernetes Secret in the same namespace. Your workloads can mount or reference this Secret to authenticate against the Nauthera token endpoint without any human interaction.
Example
apiVersion: auth.nauthera.io/v1alpha1
kind: NautheraServiceAccount
metadata:
name: payment-service
namespace: payments-prod
spec:
displayName: "Payment Processing Service"
scopes:
- "api:payments"
- "api:ledger:read"
tokenTtl:
accessToken: 5mApply it:
kubectl apply -f serviceaccount-payment.yamlThe operator creates a Secret with the credentials:
kubectl get secret payment-service-secret -n payments-prod -o yamlSpec Reference
spec.configMapName
Type: string | Optional
Name of the ConfigMap the operator creates with token endpoint and issuer configuration. Defaults to {resource-name}-config.
spec.displayName
Type: string | Optional
Human-readable name for the service account, used in audit logs and admin UI. Defaults to the resource name if omitted.
spec.scopes
Type: []string | Required
OAuth2 scopes this service account is permitted to request.
spec.secretName
Type: string | Optional
Name of the Secret the operator creates with generated credentials. Defaults to {resource-name}-secret.
spec.secretRotation
Type: object | Optional
Automatic credential rotation settings.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
enabled | boolean | No | false | Enable automatic rotation. |
grace | string | No | "24h" | Grace period during which both old and new secrets are valid (e.g. "24h"). |
rotationInterval | string | No | "90d" | Rotation interval (e.g. "90d", "30d"). |
spec.staticClaims
Type: map[string]string | Optional
Static claims to include in tokens issued to this service account. Merged with policy claim mappings; takes precedence for same claim names.
spec.tokenTtl
Type: object | Optional
Override token lifetimes for this service account. Values are clamped by applicable policy maximums.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
accessToken | string | No | — | Lifetime of access tokens issued to this service account (e.g. "1h", "30m"). |
Provisioned Resources
When you create a NautheraServiceAccount, the operator provisions two resources in the same namespace: a Secret with sensitive credentials and a ConfigMap with non-sensitive endpoint configuration. Together they contain everything a workload needs to request tokens — no hardcoded URLs required.
The operator sets owner references on both — deleting the NautheraServiceAccount also deletes the Secret and ConfigMap.
Secret
Contains the sensitive credentials only:
apiVersion: v1
kind: Secret
metadata:
name: payment-service-secret
namespace: payments-prod
ownerReferences:
- apiVersion: auth.nauthera.io/v1alpha1
kind: NautheraServiceAccount
name: payment-service
type: Opaque
data:
client_id: <base64>
client_secret: <base64>ConfigMap
Contains the token endpoint, issuer URL, and other non-sensitive metadata. Workloads use this to discover where to request tokens without fetching the OIDC discovery document at startup.
apiVersion: v1
kind: ConfigMap
metadata:
name: payment-service-config
namespace: payments-prod
ownerReferences:
- apiVersion: auth.nauthera.io/v1alpha1
kind: NautheraServiceAccount
name: payment-service
data:
issuer_url: "https://auth.example.com"
token_endpoint: "https://auth.example.com/oauth2/token"
jwks_uri: "https://auth.example.com/.well-known/jwks.json"
client_id: "sa-a1b2c3d4-e5f6-7890-abcd-ef1234567890"
scopes: "api:payments api:ledger:read"Using the Resources in a Pod
Mount both the Secret and ConfigMap for a complete setup with zero hardcoded values:
apiVersion: apps/v1
kind: Deployment
metadata:
name: payment-worker
namespace: payments-prod
spec:
template:
spec:
containers:
- name: worker
image: myregistry/payment-worker:latest
envFrom:
# Non-sensitive config (token endpoint, issuer, scopes)
- configMapRef:
name: payment-service-config
# Sensitive credentials (client_id, client_secret)
- secretRef:
name: payment-service-secretOr mount selectively:
env:
- name: OAUTH_TOKEN_ENDPOINT
valueFrom:
configMapKeyRef:
name: payment-service-config
key: token_endpoint
- name: OAUTH_CLIENT_ID
valueFrom:
secretKeyRef:
name: payment-service-secret
key: client_id
- name: OAUTH_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: payment-service-secret
key: client_secretYour application then requests tokens using the standard OAuth2 client credentials flow:
curl -s -X POST "$OAUTH_TOKEN_ENDPOINT" \
-u "$OAUTH_CLIENT_ID:$OAUTH_CLIENT_SECRET" \
-d "grant_type=client_credentials" \
-d "scope=api:payments api:ledger:read"Status
| Field | Type | Description |
|---|---|---|
clientId | string | The generated client ID. |
configMapRef | string | Name of the endpoint ConfigMap. |
lastReconciled | string | Last time the resource was reconciled. |
lastRotation | string | Timestamp of the last credential rotation. |
message | string | Human-readable message about current state. |
nextRotation | string | Timestamp of the next scheduled rotation. |
observedGeneration | integer | Current observed generation. |
ready | boolean | Whether the service account is fully reconciled and ready. |
secretRef | string | Name of the credentials Secret. |
NautheraServiceAccount vs OidcClient
| NautheraServiceAccount | OidcClient | |
|---|---|---|
| Use case | Service-to-service / machine-to-machine | User-facing applications |
| Grant types | client_credentials only | authorization_code, refresh_token, client_credentials, token exchange |
| Redirect URIs | Not applicable | Required |
| Login flow | None — tokens are issued directly | User authenticates via login page |
| Consent screen | Not applicable | Configurable |
| PKCE | Not applicable | Configurable |
| Credential rotation | Built-in automatic rotation | Manual (re-create the OidcClient) |
Use a NautheraServiceAccount when a workload needs to authenticate itself — not a human. Use an OidcClient when users need to log in.
Multi-Environment Pattern
Like OidcClient, create one NautheraServiceAccount per environment namespace:
# payments-dev namespace
apiVersion: auth.nauthera.io/v1alpha1
kind: NautheraServiceAccount
metadata:
name: payment-service
namespace: payments-dev
spec:
scopes: ["api:payments"]
tokenTtl:
accessToken: 1h # Longer TTL for dev
---
# payments-prod namespace
apiVersion: auth.nauthera.io/v1alpha1
kind: NautheraServiceAccount
metadata:
name: payment-service
namespace: payments-prod
spec:
scopes: ["api:payments"]
tokenTtl:
accessToken: 5m # Short TTL for prod
secretRotation:
enabled: true
rotationInterval: 30dRelated Resources
- OidcClient — For user-facing applications with login flows.
- AuthPolicy — Policies governing scope restrictions and token settings.
- Endpoints — Token endpoint reference for the client credentials grant.
- Quick Start — End-to-end example including client credentials flow.