Start a hosted gateway sign-on for a paying tenant (fleet operator)
Device-authorization grant (RFC 8628 shaped) by which a paying tenant
of the AgentSafe hosted gateway fleet receives its workspace key
without anyone copying one. The fleet operator (Tenant.py) starts it
with a Microsoft Entra access token for
api://decionis-operator/Operator.Act whose roles holds the operator
role; who asked (oid, sign-in name) is recorded from the verified
token, never from the body, and a body naming a requester is refused.
The customer then approves at verification_uri_complete while signed
in to Decionis as owner_email by a sign-in that proved that address,
ADMIN or above in a workspace on a paid plan with an active
entitlement, and the operator polls the token endpoint. Codes live 30
minutes; poll every interval seconds. Twenty starts per hour per
operator. Without Entra configuration
(DECIONIS_OPERATOR_ENTRA_TENANT_ID, DECIONIS_OPERATOR_ENTRA_CLIENT_ID,
and a well-formed DECIONIS_OPERATOR_ENTRA_CLIENT_APPS when set) every
call answers 503 OPERATOR_AUTH_NOT_CONFIGURED.
Authorization
OperatorEntraAuth A fleet operator's Microsoft Entra v2 access token for the
"Decionis Operator API" app registration (Application ID URI
api://decionis-operator), as az account get-access-token --scope api://decionis-operator/Operator.Act returns it: issuer
https://login.microsoftonline.com//v2.0, audience the app's
client id, scp holding Operator.Act, roles holding
HostedGateway.Operator (or DECIONIS_OPERATOR_ENTRA_ROLE), and azp
Azure CLI (04b07795-8ddb-461a-bbee-02f9e1bf7b46) or a client
DECIONIS_OPERATOR_ENTRA_CLIENT_APPS names (403
OPERATOR_CLIENT_NOT_ALLOWED otherwise), verified against the tenant's
JWKS. The app registration should make Operator.Act admin-consent
only and require assignment on its enterprise application.
In: header
Request Body
application/json
The tenant id in the fleet registry; www, api, status, admin and console are reserved.
^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$Where the tenant is served, <tenant_label>.<fleet domain>.
length <= 253The tenant's upstream, https without credentials, query or fragment; its origin is what the customer is shown and approves.
length <= 2048Only a signed-in user with exactly this email (case-insensitive) may approve or deny.
emaillength <= 320The tenant's embedding limit, so the approval page states it exactly.
1 <= value <= 1677721665536Response Body
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/hosted-gateway/authorizations" \ -H "Content-Type: application/json" \ -d '{ "tenant_label": "acme", "tenant_host": "acme.decionisedge.com", "upstream": "https://api.acme.example", "owner_email": "user@example.com" }'{ "authorization_id": "be63c26c-03c0-4635-ae2b-58f14bd033f9", "device_code": "string", "user_code": "string", "verification_uri": "https://decionis.com/connect/edge", "verification_uri_complete": "https://decionis.com/connect/edge?code=BCDF-GHJK", "expires_in": 1800, "interval": 5}Grant a workspace capacity for more hosted gateways (fleet operator) POST
The fleet operator, with their own Microsoft Entra token (GatewayOperations.py limit), sets how many hosted gateways the workspace may hold, from 1 to 10. Core locks the workspace, refuses a limit below the gateways it already holds, and records the verified operator and the reason in hosted_gateway.limit.changed. It changes neither billing nor any customer consent, and accepts no operator identity, plan or workspace key from the body. Twenty calls per hour per operator.
Poll a hosted gateway sign-on for its workspace key (fleet operator) POST
The operator's poll, with the same Entra token as the start: a device code redeems only for the operator who started it. Until the customer decides, it answers `authorization_pending` (or `slow_down`, with a 5 s wider `interval`, when polled sooner than the interval allows). Once approved, the next poll first applies approval's workspace rules again (the approver ADMIN or above, a paid plan, an active entitlement); a workspace that no longer qualifies denies the authorization (`access_denied` with a `reason`), and Accounts being unreachable answers 503 `temporarily_unavailable` to retry, nothing minted. Otherwise it mints the key in the same transaction that consumes the authorization and makes it the tenant's current key (one per organization and tenant label), and returns it exactly once: a MEMBER key named `agentsafe-hosted-<tenant_label>` with scopes `["decision:shadow"]`, created by the approver. The key expires at `confirm_by` (10 minutes) unless the holder calls POST /v1/hosted-gateway/keys/confirm with it, so a key whose delivery was never confirmed does not stay active. The tenant's earlier keys (`replaced_key_ids`) stay live until that confirmation revokes them, except one that was itself never delivered, which is revoked now; a new key that is lost in transit never leaves the tenant without one. Later polls answer `invalid_grant`. Sixty polls per minute per operator.

