> ## Documentation Index
> Fetch the complete documentation index at: https://docs.knoxcall.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Azure (Functions, App Service, AKS, VMs)

> Authenticate from Azure workloads to KnoxCall using Managed Identity

# Azure Workload Identity

Azure workloads with a system-assigned or user-assigned Managed Identity get a local metadata endpoint that issues short-lived tokens. KnoxCall accepts these via RFC 8693.

## 1. Enable Managed Identity on your resource

Azure portal: **Identity → System assigned: On** (or attach a user-assigned identity).

This sets the env vars on every request:

* `IDENTITY_ENDPOINT` — local metadata URL
* `IDENTITY_HEADER` — header value the metadata service requires

## 2. Configure the trust binding

Create the binding in the dashboard with **Settings → API → Workload Identity → Connect workload**, or call the admin API on the admin host (`admin.knoxcall.com`). The admin API is authenticated by your dashboard session JWT plus an `X-Tenant-ID` header (it is **not** the API-key data plane on `api.knoxcall.com`).

<Note>
  Creating a binding requires a **recent step-up verification** (passkey, TOTP or
  emailed code) within the last 5 minutes — a binding is a trust that lets an
  external workload mint tenant tokens, so it carries the same bar as creating an
  OAuth client. A `curl` carrying only a session JWT answers
  `403 {"requires_step_up": true}`: verify in the Dashboard (any action that
  prompts for your passkey or TOTP), then replay the request inside the 5-minute
  window. Each verification is single-use, so a retried request needs a fresh one.
  Listing and revoking bindings need no verification — containment must never be
  gated.
</Note>

```bash theme={"dark"}
curl -X POST https://admin.knoxcall.com/admin/oauth/workload-bindings \
  -H "Authorization: Bearer $SESSION_JWT" \
  -H "X-Tenant-ID: $TENANT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "oauth_client_id": "<your_oauth_client_id>",
    "name": "azure-prod-functions",
    "issuer": "https://login.microsoftonline.com",
    "audience": "knoxcall:api",
    "attribute_conditions": {
      "oid": "<managed-identity-object-id>"
    },
    "allowed_scopes": ["routes:read"],
    "access_token_ttl_seconds": 3600
  }'
```

Lock to the Managed Identity object id (`oid` claim). You can also lock `tid` (tenant) or `appid` for tighter control.

## 3. Call KnoxCall

```javascript theme={"dark"}
import { KnoxCall } from "@knoxcall/sdk";
const client = new KnoxCall({ tenant: "acme" });
await client.routes.list();
```

The SDK calls `$IDENTITY_ENDPOINT?resource=knoxcall:api` with the `X-IDENTITY-HEADER`, gets the JWT, exchanges it for a KnoxCall token.

## Troubleshooting

* **`Could not detect KnoxCall credentials`** — Managed Identity isn't enabled or env vars aren't propagated. Check the resource's Identity blade.
* **`invalid_target`** — `resource` param in the metadata call must be exactly `knoxcall:api`; we set this automatically.
* **`invalid_grant: no binding matched`** — verify the `oid` of your Managed Identity (run `az identity show --ids <resource-id> --query principalId`) matches the binding.
