Exchanges a machine credential for an IAM bearer token.
Exchanges a machine credential for an IAM bearer token.
POST /v1/kms/auth/login
| Address | https://api.hanzo.ai/v1/kms/auth/login |
| Method | POST |
| Operation | post_kms_auth_login |
| Auth | Authorization: Bearer $HANZO_API_KEY |
Exchanges a machine credential for an IAM bearer token.
Takes a tenant's machine credential — a client id and client secret — and returns an owner-scoped IAM access token with its lifetime, which is the bearer the caller then carries on the org-scoped secret operations.
It is deliberately public and unauthenticated, because it IS the credential exchange and runs before any principal exists. That makes it the one route in this subsystem rate-limited PER SOURCE IP, keyed on the real TCP peer rather than on any caller-supplied header, and body-capped at the same door.
The submitted secret is never logged and never echoed, and failures collapse to one clean status with no upstream detail: 401 when the credential does not authenticate, 502 when the identity provider is unreachable, 503 when no issuer is configured. That is on purpose — a richer error would be a validity oracle for guessed credentials.
Request
2 fields, body application/json (required).
| Field | In | Type | Required | Description |
|---|---|---|---|---|
clientId | body | string | — | ClientID is the machine identity's id, as IAM issued it. |
clientSecret | body | string | — | ClientSecret is that identity's secret. |
Response
| Status | Body | Meaning |
|---|---|---|
200 | kmsToken | ok |
200 body — 3 fields.
| Field | In | Type | Always | Description |
|---|---|---|---|---|
accessToken | body | string | — | AccessToken is IAM's own JWT, verbatim. |
expiresIn | body | integer | — | ExpiresIn is the token's lifetime in seconds, as IAM reported it. |
tokenType | body | string | — | TokenType is Bearer. |
Failure carries the platform error shape — see Errors.
Examples
hanzo kms auth loginimport { Configuration, KmsApi } from 'hanzoai';
const api = new KmsApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.postKmsAuthLogin({ clientId: "<clientId>", clientSecret: "<clientSecret>" });from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import KmsApi
client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = KmsApi(client).post_kms_auth_login(client_id="<clientId>", client_secret="<clientSecret>")cfg := cloud.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := cloud.NewAPIClient(cfg)
resp, _, err := client.KmsAPI.PostKmsAuthLogin(context.Background()).Execute()
if err != nil {
return err
}use hanzo_cloud::apis::{configuration::Configuration, kms_api};
let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();
let result = kms_api::post_kms_auth_login(&cfg, Default::default()).await?;import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.KmsApi;
ApiClient client = new ApiClient();
client.setRequestInterceptor(b -> b.header("Authorization", "Bearer " + System.getenv("HANZO_API_KEY")));
var result = new KmsApi(client).postKmsAuthLogin();curl -X POST https://api.hanzo.ai/v1/kms/auth/login \
-H "Authorization: Bearer $HANZO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"clientId": "<clientId>",
"clientSecret": "<clientSecret>"
}'The door reaches kms through the kms tool, which names its 2 operations with its own verbs — this one among them, under a name only the door declares. describe explains any of them:
curl -X POST https://api.hanzo.ai/v1/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "describe",
"arguments": {
"op": "get_kms_config"
}
}
}'How is this guide?