Agent Workload Identity
Overview
Section titled “Overview”An agent’s name is a selector; a signed workload token proves its
provider-issued identity. In direct mode, the SDK presents that token in
X-Agent-Token, verified against the selected provider’s own key set. Entra
also supports gateway runtime authentication: the gateway verifies the approved
runtime key and any required cloud identity, exchanges its blueprint credential
for the exact Entra child, and issues a short-lived session bound to the runtime
key. The SDK proves possession of that key on each session-backed request.
Without a provider the
agent is trusted on the strength of its Virtual Key alone, which is appropriate
for local development and not much else.
Configure providers under Agentic → Identities → Identity providers, then review a discovered agent under Agents → Needs attention → Review. Verified proof or an explicit VK-trusted approval determines its trust state. Use Identity & credentials for later changes to an active agent.
For server-managed LangGraph execution, the same review configures the worker’s identity and authorizes its separate server runtime key. The saved submission can progress without rerunning the client. Local client keys are separate approvals; the worker never imports a client’s private key.
Captured 10 October 2026 with synthetic demonstration data.
Supported provider types
Section titled “Supported provider types”| Type | Use it for |
|---|---|
entra_agent_id | Microsoft Entra Agent ID. Constrained to approved Microsoft authority hosts. |
generic_oidc | Signed JWT access tokens from a compatible OAuth issuer, with an exact audience and mapped workload identity. |
zeroid | ZeroID-issued agent identities; requires a configured exchange endpoint and workload assertion. |
The provider editor offers Entra and Generic OIDC. SPIFFE subject parsing and endpoint validation are implementation groundwork, not a complete supported SDK-to-gateway JWT-SVID onboarding flow. Do not select it for a production deployment until the runtime adapter and credential integration are available.
Endpoints are validated before the gateway dials them: no cloud metadata address is ever reachable, and the hostname is resolved by the same client that connects, so a DNS answer cannot change between validation and the connection.
Configure once, then review each agent
Section titled “Configure once, then review each agent”For a complete fresh Microsoft setup and a laptop-hosted gateway, follow
Microsoft Entra with a local gateway.
It covers the gateway API, blueprint, management permissions, pasted
credentials, automatic Gateway.Invoke assignment and every test2.py review
step at http://localhost:8080.
Create one identity for each logical agent and security boundary, usually with separate identities for development and production. Repeated runs, replicas, and token refreshes reuse that identity. A human owner can own many agents; neither every run nor every person starting the same workload needs a new client registration. Agents that need independent permissions, revocation, or audit attribution need separate identities.
Entra gateway runtime authentication: minimum steps
Section titled “Entra gateway runtime authentication: minimum steps”Use this path when the gateway should hold the Entra blueprint runtime credential and the existing agent script should enroll its own runtime key. It requires SDK and gateway builds containing runtime authentication; updating the browser alone does not enable it on an older gateway.
-
Prepare the Entra tenant, approved agent identity blueprint, and gateway API audience. Define the gateway API’s
Gateway.Invokeapplication role; the broker requires that role in the verified child token. Provisioning can assign it during creation with the explicit opt-in in step 3, or the Entra administrator can assign it after creating the child. Provisioning Graph permissions and gateway invocation permissions are separate. -
Open Agentic → Identities → Identity providers. Create or edit the Entra provider, set its tenant, blueprint, issuer and gateway audience, and use Shared agents · explicit identity list for multiple children. Under Runtime authentication, a new Entra provider defaults to Gateway exchanges Entra token · recommended; keep it and enable Gateway exchange enabled. Workload supplies Entra token · Azure-hosted workloads only is an explicit choice: the workload host itself must hold an Entra credential (environment variables, workload identity federation or a managed identity, tried once in that order; the SDK fails fast with a single error line when none is present). A brand-new agent’s first run can submit a provisional runtime key before its identity exists: a workspace with one validated gateway-exchange Entra provider uses it automatically, and with several, Default for new registrations selects the one that receives those keys. Choose one blueprint runtime credential from the table below, then save and validate the provider.
-
Complete Provisioning → Authorize provisioning once for this workspace and provider, using the separate Graph management credentials. To include the invocation grant in the same creation job, select Assign Gateway.Invoke when creating agents after the management application has the additional consent described below. Use Create or link identity for
math-agent, select its active human owner, and wait for Completed. This declaresagent:math-agentagainst the exact Entra child. An existing matching declaration does not need to be recreated. -
Install
deepintshield[runtime]3.2.0 or newer in the Python environment runningtest2.py. Supply four settings: the gateway URL (DEEPINTSHIELD_BASE_URL), the active workspace reporting Virtual Key (DEEPINTSHIELD_VIRTUAL_KEY), the agent namemath-agent(DEEPINTSHIELD_AGENT_NAME) and the developer’s work e-mail (DEEPINTSHIELD_REGISTERED_BY). Run the existing saved script once. The SDK discovers the gateway mode, enrolls its public runtime key and stops withRegistration pending. Reference <registration id> · runtime key SHA256:<thumbprint>. Contact your administrator. You will be notified at <email>.The administrators receive a review-needed e-mail. No Entra blueprint or management secret is copied intotest2.py. -
One review sitting. Open Agents → Needs attention and select Review for
math-agent. Confirm the Accountable owner proposed from the registering e-mail, or choose another; confirm the child from step 3 under Identity & owner, or create or link it here. In Runtime access, compare the Key fingerprint with the thumbprint printed to the developer and, under Details, the Agent, Entra child and Provider against the intended deployment. Select Authorize runtime key, choose Approved runtime key · any host for local development or a cloud identity policy below, and confirm the exact key. Review Code & changes and Tools & access, then in Review & decide select Approve now, activates on the agent’s next run and confirm with Approve now · activates on next run. The reviewer must not be the accountable owner. -
Run
test2.pyagain. The gateway verifies the runtime key and the Entra exchange, applies the recorded decision and the agent executes; the review then shows Runtime proof and Entra exchange as Verified. A script changed after the decision was recorded reports pending again and needs a new review. The recorded decision grants every action the administrator selected, so the whole agent runs; the Decision recorded card lists the actions that activation will grant. See Deferred activation.Gateways without deferred activation use the earlier sequence: authorize the key, run
test2.pyto collect proof, complete owner, code and access review with Preview approval → Confirm approval and access, then run again.
| Blueprint runtime credential | Configure once on the gateway |
|---|---|
| Client secret · development | Paste the Blueprint client secret VALUE and explicitly select This gateway runtime connection is for development. This is the blueprint’s secret, not the Graph management application’s secret. |
| Certificate | Register the public certificate on the blueprint, then enter Certificate PEM and its matching Private key PEM. The gateway stores the credential encrypted. This option does not require an Azure-hosted gateway. |
| Gateway Azure managed identity | Configure Entra federation from the gateway host’s Azure managed identity to the blueprint. Enter the user-assigned identity’s client ID, or leave it empty for system-assigned identity. This credential option requires the gateway host to have that Azure identity; it does not require the agent to run on Azure. |
The gateway never returns stored secret values in its configuration API.
For Entra v2 tokens, configure the verification audience as the gateway API’s
application client ID (UUID). The token request instead uses its application ID
URI with /.default. The gateway defaults to api://<application-client-id>;
if your API uses a custom URI, set Optional token scope settings → Gateway
API application ID URI. This does not change the expected JWT audience.
Preserve its encryption key with its persistent data. The SDK separately
preserves the workload’s runtime private key using the native keyring or, on
POSIX, a restricted local file. Its default descriptor directory is
~/.deepintshield/runtime-keys; deployments can select a persistent directory
with DEEPINTSHIELD_RUNTIME_KEY_DIR or mount a private key using
DEEPINTSHIELD_RUNTIME_KEY_FILE. A replacement runtime key needs a new explicit
authorization. Pausing gateway exchange blocks this mode rather than silently
switching to direct authentication.
Require the application’s native cloud identity
Section titled “Require the application’s native cloud identity”Approved runtime key · any host verifies possession of the approved key; it does not attest the machine, cloud account, or hardware. To require native cloud identity as well, choose the matching Runtime identity policy during the same runtime-key confirmation. Enter the exact Workload token issuer, Exact workload subject, Workload token audience, and Workload signing keys (JWKS URL). The gateway verifies all four as well as the runtime key. Issuer and signing-key endpoints must be HTTPS and reachable by the gateway.
The workload opts into native credential access through the following
non-secret deployment settings. The approved workload-token audience is supplied to
the SDK; DEEPINTSHIELD_RUNTIME_AUDIENCE can additionally pin it locally.
| Application host | Workload deployment settings and prerequisites |
|---|---|
| GCP | Set DEEPINTSHIELD_RUNTIME_KIND=gcp on a host exposing Google’s service-account identity-token metadata endpoint. Pin that service account’s token subject and issuer in the binding. |
| AWS | Enable outbound identity federation, authorize the workload to call sts:GetWebIdentityToken, and install deepintshield[runtime-aws]. Set DEEPINTSHIELD_RUNTIME_KIND=aws and DEEPINTSHIELD_RUNTIME_AWS_REGION to the regional STS endpoint’s region. Pin the account’s returned IssuerIdentifier, its /.well-known/jwks.json, the exact token subject, and the selected audience. The issuer is account-specific; it is not the regional STS request URL. |
| Azure | Set DEEPINTSHIELD_RUNTIME_KIND=azure on a managed-identity host. Use DEEPINTSHIELD_RUNTIME_AZURE_CLIENT_ID for a user-assigned identity; omit it for system-assigned identity. Azure VM metadata is supported; Azure managed hosts exposing their own identity endpoint also need the azure extra. Pin the actual token’s issuer, subject, audience and signing keys. |
| Kubernetes | Set DEEPINTSHIELD_RUNTIME_KIND=kubernetes and DEEPINTSHIELD_RUNTIME_TOKEN_FILE to an explicitly projected, audience-specific service-account token file. Pin the cluster’s issuer/JWKS and exact service-account subject. The default Kubernetes API token is not selected automatically. |
These application identities are independent of the gateway’s blueprint credential. For example, an AWS-hosted application can use AWS outbound identity federation while the gateway authenticates to Entra with a certificate. Cloud selection alone is not evidence: proof appears only after a successful runtime verification and Entra exchange. The broker does not bypass source review, tool permissions, or per-request authorization.
Provision identities from DeepIntShield
Section titled “Provision identities from DeepIntShield”Use Agentic → Identities → Provisioning to connect management access, create or link identities, and track their lifecycle. This is separate from the Identity providers tab, which configures token verification. Management credentials are never agent runtime credentials.
Use a workspace with the Agentic identity feature and an operator who can create or update Agentic records. Select the intended tenant and workspace before creating the provider, owner, connection, or agent. This flow describes the current SDK 3.2.0 / Server 3.2.0 implementation; use deployed builds containing these features, since a version label alone does not establish which changes are installed.
- Configure, enable, and validate the runtime identity provider, including its issuer and gateway audience.
- Have the customer’s identity administrator authorize a provisioning client and the permitted workspace, blueprint or realm. For Entra, prepare its application client ID, client secret value, and approved sponsor IDs.
- In Provisioning, choose Authorize provisioning, select the matching runtime provider, and use Paste credentials for Entra. The gateway stores the management secret encrypted. Server environment references remain available for Entra and are used by the other connectors. Issuer, audience, and the Entra directory/blueprint are inherited from that verifier and shown read-only. Run Check connection.
- Choose Create or link identity, select an active human owner, and keep a stable agent key and deployment environment. A durable job creates or finds the external identity and saves its expected identity declaration.
- Configure the workload for direct credentials or the gateway runtime path above, run the agent to send fresh proof, and finish the registry review. Creating an identity does not approve code or grant tool access.
For a new shared Entra verifier, use Agent admission → Shared agents · explicit identity list. Save and validate it before creating the first child. An empty list admits no workload; provisioning adds the exact created or linked child IDs. No placeholder child ID or separate verifier per agent is needed. Existing single-child settings remain unchanged; explicitly switching them to shared mode carries only the currently admitted child into the list. Saved list, prefix, and any predicates retain their policy. A preserved Default child client ID supports older manual configuration and does not add a child to the shared admission list.
For Keycloak, Auth0 and Okta, use a shared Generic OIDC verification provider
with the token’s sub mapped to the principal and without a provider-wide
client-ID default. Each workload receives its own client ID from its credential
destination. Provisioning refuses an incompatible single-client pin instead of
silently widening it. Customized token-subject transformations require a
separately supported connector mapping; fresh workload proof is always checked.
| Connector | Customer setup | Credential delivery |
|---|---|---|
| Entra Agent ID | Existing approved blueprint, Graph management authorization, approved sponsor object IDs, and the selected direct or gateway runtime credential | Uses the blueprint credential/federation; no child client secret is created |
| Keycloak | Existing realm and a restricted client permitted to manage the intended realm’s service clients | Generated client secret delivered to Vault KV v2 |
| Auth0 | Management API authorization to manage clients and the approved API’s client grants | Vault KV v2 client secret, or registered RSA public keys |
| Okta | Authorized management service app and a custom authorization server with the required audience, scopes, and access policy | Vault KV v2 client secret, or registered RSA public keys |
Connector capabilities determine which actions appear. All four support create, link, and check; disable and retire apply only to identities DeepIntShield manages. Linked identities remain read-only and use their existing workload credential delivery. Okta public-key rotation adds keys while retaining existing keys for an overlap period; it does not remove old keys. The other connectors do not offer rotation, and no connector offers automatic client-secret rotation.
Captured 10 October 2026 with synthetic demonstration data.
Understand the provisioning records
Section titled “Understand the provisioning records”| UI area | What it records |
|---|---|
| Identity providers | Runtime token verification settings; enabling and validating a verifier does not authorize management access. |
| Provisioning → Connections | Customer-approved management connections to those verifiers. A verifier can exist before any provisioning connection. |
| Provisioning → Created & linked | Identities recorded by provisioning create or link jobs. The count excludes manual identity declarations. |
| Provisioning → Created & linked, cards marked Declaration | Expected identity reservations that have no corresponding provisioning record. A declaration is not workload proof. |
| Provisioning → Activity | Provisioning and lifecycle jobs, separate from registration approval. |
It is valid to see 0 created or linked identities while declarations already exist. Check the declaration and its current claimant before creating another identity or changing the workload’s name. To record an existing external identity through this tab, use the authorized link flow; linked identities remain read-only.
Authorize an Entra connection in the UI
Section titled “Authorize an Entra connection in the UI”Start with an enabled, tested Entra verifier. In Identity providers, select the provider and check Directory tenant, Audience (verify), Blueprint application, and the generated Authority and JWKS URI. Blueprint application is the existing parent blueprint’s application/client ID. Save, then Test, validates the saved configuration; the embedded registration editor offers Save & validate. Workload identity still needs a credentialed run.
Paste credentials is ready to use without configuring an environment
variable or encryption key. The gateway encrypts management credentials
automatically. If an encryption_key is already configured, it continues to use
that key; otherwise, it creates and reuses provisioning-credentials.key in its
persistent application data directory.
Preserve this key file with the gateway data across restarts and backups. Replicas that share stored credentials must use the same key and persistent data volume. If secure storage is unavailable, check the gateway data directory and server logs; credentials cannot be saved until the storage problem is fixed.
In Microsoft Entra, open the authorized management application’s App registrations → Overview and copy Application (client) ID. Under Certificates & secrets → Client secrets, create a secret if needed and copy its Value while it is visible. Enter that value in DeepIntShield; the secret’s ID is a different field. See Microsoft’s application credential setup.
The management application must have approved Graph permissions and consent
for the intended operations. Check connection lists agent identities;
Microsoft’s list API
documents AgentIdentity.Read.All. Creating also needs authorization described
by the create API,
such as AgentIdentity.Create.All or AgentIdentity.CreateAsManager. Grant
management access to the provisioning application.
To assign the gateway invocation role inside the existing create job, also
grant that management application the Microsoft Graph application
permissions AppRoleAssignment.ReadWrite.All and Application.Read.All, then
grant administrator consent once. Microsoft documents these permissions in
Grant an app role assignment.
The opt-in below authorizes only the Gateway.Invoke role on the resource
matching this connection’s gateway audience, for owned children created or
reconciled by provisioning. Linked external identities keep their existing
grants. Turning the option off does not revoke Entra grants already assigned.
For a managed identity on an opted-in connection, Check identity also
assigns a missing gateway invocation role. Its confirmation describes that
change. Check connection only checks connection access and resolves the
gateway role; it does not assign a role to a child.
Open Provisioning → Authorize provisioning:
| Field | What to enter |
|---|---|
| Connection name | A label such as development-entra-provisioning. |
| Management provider | Microsoft Entra. |
| Workload verification provider | The enabled Entra verifier just configured. |
| Verification settings | Check the inherited Token issuer, Gateway audience, Directory tenant, and Authorized blueprint. These are read-only in this form. |
| Management URL | https://graph.microsoft.com. |
| Allowed scopes | Space-separated workload scopes approved for this connection. Leave empty when none are configured; this field does not grant Microsoft Graph management permissions. |
| Assign Gateway.Invoke when creating agents | Off by default. Select after the one-time Graph permission/consent above to include the exact gateway invocation role in the same creation job. Changing the selected verifier, audience, tenant or blueprint clears this opt-in for review. |
| Management credentials | Keep Paste credentials, the default for a new Entra connection. |
| Management application (client) ID | The authorized management application’s Application (client) ID. |
| Client secret VALUE | The management application’s client secret Value. |
| Sponsor user object IDs / Sponsor group object IDs (optional) | Approved Entra user or group UUIDs, separated by commas, spaces, or newlines, with one to ten total IDs across both fields. The local accountable owner’s name does not supply these IDs. |
| Allowed existing child identity IDs (optional) | Exact Entra child agent identity IDs this workspace may link. Leave empty when only creating new children. |
| Connection enabled | On. |
Entra uses the existing blueprint federation and does not generate a child client secret or ask for a credential delivery reference.
Click Save connection, then Connections → Check connection. Under Activity, wait for that job to show Completed. This checks server authorization and a live Graph read; a successful check does not prove the workload or guarantee that every later management operation has permission.
The saved secret is not returned by the API or displayed when reopening the connection. Leave the secret field empty to retain it for the same management client ID; enter a new value to replace it. Changing the client ID requires its own secret. DeepIntShield generates and preserves the internal ownership key used to reconcile provisioning retries. Entra requires a valid sponsor reference when creating an agent; its create API example shows user and group references. This connector requires the sponsor IDs when checking or linking a connection as well.
To use an existing server-managed configuration instead, select Server
environment reference and enter its Management credential reference, such
as env:DEEPINTSHIELD_PROVISIONING_ENTRA. See
Entra server authorization below.
Link an existing Entra identity or create a child
Section titled “Link an existing Entra identity or create a child”Open Create or link identity and select the checked Connection. Choose Link existing when the child already exists. Choose Create new when this logical agent needs a new child under the approved blueprint.
| Field | What to enter |
|---|---|
| Agent key | A stable key such as invoice-assistant-dev, using lowercase letters, numbers, underscores, or hyphens. Use the same value in DEEPINTSHIELD_AGENT_NAME on every run. |
| Display name | A readable label; it does not replace the key or token identity. |
| Accountable owner | An active human from Identities → Users. Create or activate that directory entry first if the selector is empty. |
| Environment | The deployment environment, for example development. |
| Existing provider object ID (link only) | The existing Entra agent identity object’s Graph id, authorized in Allowed existing child identity IDs or the environment configuration’s linkable_external_ids for this workspace. |
| Expected token identity (link only) | For this Entra connector, the same child agent identity ID. For generic OIDC connectors, use the exact token principal instead; it may differ from the OAuth client ID. |
The Entra connector verifies that Graph returns an agentIdentity under the
connection’s blueprint. It records that object’s id as the child client ID
and expected identity. An ordinary application registration’s object ID, the
parent blueprint ID, and a human owner’s ID are not substitutes. Obtain the
child ID from the identity administrator rather than guessing from its name.
Click Link identity or Create identity. Track the job in Activity until Completed, then use Run and verify this agent. A completed job records the expected identity declaration automatically and adds the exact child to an eligible Entra admission list when needed, preserving already admitted children. Existing prefix/any policies must already admit the child. There is no need to click Declare again after successful provisioning.
An existing declaration for the same agent key, provider, and child can be recorded through Link existing. Create new does not replace that declaration. If another agent owns the claim, inspect the named claimant and follow Recovery and retirement. Do not create a second identity merely because Created & linked is zero.
Server authorization and secret delivery
Section titled “Server authorization and secret delivery”Entra’s Paste credentials stores its management secret encrypted and binds
the saved authorization to the current tenant, workspace, verifier, and
blueprint. It derives the Microsoft token endpoint from the directory tenant
and uses https://graph.microsoft.com/.default for management access. Runtime
workload credentials and blueprint host federation still require separate setup.
Server environment reference remains supported for all connectors. This
mode accepts references named env:DEEPINTSHIELD_PROVISIONING_*; the
corresponding environment variable holds server-managed JSON. Its tenant,
allowed workspaces, provider, issuer, audience, realm or blueprint, scopes,
and delivery destination must match the saved connection. A workspace operator
cannot widen this reference’s authorization in the UI. Inject that JSON through
the deployment’s secret manager; do not paste it into the reference field or
put it in source control or the workload environment.
Entra server authorization
Section titled “Entra server authorization”This alternative is for Server environment reference; skip it when using
Paste credentials. For example, inject the following JSON as the gateway’s
DEEPINTSHIELD_PROVISIONING_ENTRA environment variable, then enter only
env:DEEPINTSHIELD_PROVISIONING_ENTRA in the UI. Every identifier below is a
placeholder. tenant_id and allowed_workspaces identify DeepIntShield’s scope;
directory_tenant_id identifies the customer’s Microsoft Entra directory.
{ "tenant_id": "DEEPINTSHIELD_TENANT_ID", "allowed_workspaces": ["DEEPINTSHIELD_WORKSPACE_ID"], "provider_type": "entra_agent_id", "base_url": "https://graph.microsoft.com", "issuer": "https://login.microsoftonline.com/ENTRA_DIRECTORY_TENANT_ID/v2.0", "directory_tenant_id": "ENTRA_DIRECTORY_TENANT_ID", "blueprint_id": "ENTRA_BLUEPRINT_APPLICATION_ID", "audience": "GATEWAY_TOKEN_AUDIENCE", "assign_gateway_invoke": false, "allowed_scopes": [], "delivery_ref": "", "ownership_key": "REPLACE_WITH_A_STABLE_RANDOM_SECRET_OF_AT_LEAST_32_CHARACTERS", "sponsor_object_ids": ["ENTRA_SPONSOR_USER_OBJECT_ID"], "sponsor_group_ids": [], "token_endpoint": "https://login.microsoftonline.com/ENTRA_DIRECTORY_TENANT_ID/oauth2/v2.0/token", "client_id": "AUTHORIZED_MANAGEMENT_CLIENT_ID", "client_secret": "INJECT_FROM_CUSTOMER_SECRET_MANAGER", "token_scope": "https://graph.microsoft.com/.default", "linkable_external_ids": { "DEEPINTSHIELD_WORKSPACE_ID": ["EXISTING_ENTRA_CHILD_AGENT_ID"] }}Replace directory, blueprint, sponsor, and child placeholders with actual UUIDs.
The management permissions described above apply to both credential sources.
For an environment-reference connection, enabling automatic invocation-role
assignment also requires assign_gateway_invoke: true in this server-managed
JSON. A workspace checkbox cannot widen the reference’s authorization. In
Paste credentials mode, the checkbox is included in its encrypted
authorization automatically. If a queued job’s authorization changes, review
its connection and use Retry to adopt the current settings.
This example uses a server-managed client secret. For federation, replace
client_secret with client_assertion_file referencing an assertion file
available to the gateway; configure the corresponding Entra trust first.
The management token’s token_scope is separate from the connection’s
Allowed scopes and the runtime gateway audience.
The implementation requires one to ten total sponsor UUIDs across
sponsor_object_ids and sponsor_group_ids, including during connection checks
and linking. The administrator chooses supported Entra sponsors; the local
Accountable owner field does not populate these arrays. The link allowlist
is required for an existing child and may be omitted when only creating new
children. Preserve the ownership key and authorization bindings across gateway
restarts and replicas. Changing an environment variable in a developer’s shell
does not configure an already-running gateway process or container.
Keycloak and Vault example
Section titled “Keycloak and Vault example”For example, the value of DEEPINTSHIELD_PROVISIONING_ACME for Keycloak has this
shape (replace placeholders with customer-approved values):
{ "tenant_id": "customer-tenant", "allowed_workspaces": ["workspace-id"], "provider_type": "keycloak", "base_url": "https://sso.example.com", "issuer": "https://sso.example.com/realms/agents", "realm": "agents", "audience": "deepintshield", "allowed_scopes": ["workload"], "delivery_ref": "env:DEEPINTSHIELD_PROVISIONING_ACME_VAULT", "ownership_key": "REPLACE_WITH_A_STABLE_RANDOM_SECRET_OF_AT_LEAST_32_CHARACTERS", "token_endpoint": "https://sso.example.com/realms/agents/protocol/openid-connect/token", "client_id": "approved-provisioner", "client_secret": "INJECT_FROM_CUSTOMER_SECRET_MANAGER", "linkable_external_ids": {"workspace-id": ["approved-existing-object-id"]}}ownership_key authenticates the reconciliation marker stored on created
objects. Preserve it across restarts and replicas. linkable_external_ids
explicitly authorizes which existing objects each workspace may link.
The DEEPINTSHIELD_PROVISIONING_ACME_VAULT value identifies a Vault KV v2 sink:
{ "tenant_id": "customer-tenant", "allowed_workspaces": ["workspace-id"], "base_url": "https://vault.example.com", "mount": "secret", "path_prefix": "deepintshield/agents", "token_ref": "env:DEEPINTSHIELD_PROVISIONING_VAULT_TOKEN"}Scope the Vault token to that prefix. Provisioning stages secrets with
compare-and-set before creating a client, then marks the record ready: true
after setup succeeds. Workloads must consume only ready records. The identity
record exposes a destination reference, never the secret. Workload access to
Vault is configured separately; the gateway’s Vault token is not delivered to
agents.
For a secret-based OIDC workload, map the ready record’s client_id,
client_secret, and token_endpoint to OIDC_CLIENT_ID, OIDC_CLIENT_SECRET,
and OIDC_TOKEN_ENDPOINT, with OIDC_CLIENT_AUTH_METHOD=client_secret_post.
Map its scopes to a space-separated OIDC_SCOPES. An unset OIDC_SCOPES retains
the verification provider’s scope defaults; an explicitly empty value omits the
token request’s scope parameter. Use an SDK build containing this override.
Auth0 uses OIDC_AUDIENCE from the record’s audience. For the provisioned
Keycloak and Okta clients, set OIDC_AUDIENCE="": their access-token audience
comes from the realm’s audience configuration or custom authorization server,
rather than an audience request parameter. The gateway still verifies the
configured token audience. The SDK example
examples/agentic/provisioned_oidc.py consumes a mounted ready record and starts
the workload without printing or passing the secret on its command line; see
Provisioned workload credentials.
For Auth0 or Okta public-key authentication, set
OIDC_CLIENT_AUTH_METHOD=private_key_jwt, mount the workload’s private key as
OIDC_PRIVATE_KEY_FILE, and set OIDC_PRIVATE_KEY_KID to the registered public
key’s kid. Only the public RSA key is sent to provisioning. The secret-based
launcher example does not configure this flow or Entra federation.
Environment-configured management authentication also supports
private_key_file with key_id for RSA private_key_jwt, or
client_assertion_file for a projected Entra federation
assertion. Private key files must have restrictive permissions. Alternatively,
access_token_ref names a separately managed bearer-token reference. Use
token_scope and token_audience for the management token’s authorization;
these differ from the workload connection’s audience and scopes.
For Entra use provider type entra_agent_id, base URL
https://graph.microsoft.com, the existing directory_tenant_id and
blueprint_id (the blueprint’s application/client ID), and an issuer of
https://login.microsoftonline.com/<tenant-id>/v2.0. Supply approved
user or group sponsor IDs in Paste credentials, or sponsor_object_ids and
sponsor_group_ids in the server JSON. The local
accountable owner’s subject is not assumed to be an Entra object UUID. The
created agent identity’s id is its child client ID. Provisioning uses the
existing blueprint; it does not create its host federation or consent grants.
Common provisioning failures have specific setup causes:
| Failure | What to check |
|---|---|
credential_storage_unavailable | Check the gateway data directory and server logs for key-file or storage failures. Preserve the existing provisioning-credentials.key file or configured encryption key; the secret is not saved without encryption. |
server_reference_unavailable | The gateway process can read the named environment reference; entering its name in the UI is not enough. |
provisioner_scope_denied | DeepIntShield tenant and allowed workspace bindings match the current connection. |
provisioner_binding_mismatch | Provider, management URL, issuer, directory, blueprint, audience, and delivery reference exactly match the saved connection. |
entra_sponsor_configuration_required | The saved credentials or server JSON supply one to ten supported sponsor UUIDs. |
external_identity_link_not_authorized | The existing child ID is in Allowed existing child identity IDs or this workspace’s environment-configured link allowlist. |
provider_identity_mismatch | The selected Graph object is an Entra agent identity under this blueprint and matches the requested identity. |
management_permission_denied | The management client has the required Graph authorization for the failed operation. |
Correct the cause, then use Check connection or the failed job’s Retry. Keep the original job when reconciling an uncertain create.
Endpoints require HTTPS on port 443. Private Keycloak and Vault DNS hosts must
also be listed in the server’s comma-separated
DEEPINTSHIELD_PROVISIONING_PRIVATE_HOSTS; loopback and link-local targets remain
blocked. Redirects cannot move management credentials to another endpoint.
Recovery and retirement
Section titled “Recovery and retirement”If the verifier’s settings change, an existing connection keeps its saved settings. For an unused connection, open it and choose Use current verification settings, then Save connection and Check connection. This explicit step updates the inherited issuer, audience, and Entra tenant/blueprint in the draft; background refresh does not replace them. For Server environment reference, the reference must permit the resulting settings.
Once the connection has an identity or a job other than Check connection, its trust and delivery settings cannot be changed. Authorize a new connection for the new configuration; existing identities retain their original settings.
Provisioning runs in leased database jobs outside agent execution. Retries reconcile the deterministic identifier and authenticated ownership marker. An uncertain create is never blindly repeated: it remains in reconciliation until the provider object can be found. Retry retains the original request and reconciliation state. A provider outage or rate limit does not require re-entering the connection or submitting another create request.
Disable and Retire first quarantine local access, then perform the remote operation. A remote failure leaves local access quarantined. Retirement retains audit and proof history. A denied registration likewise does not automatically free a previously proven identity. Release declaration is available only for an unbound declaration with no recorded proof in its current or historical registration. Use Re-enrol agent when offered for the existing denied registration and complete fresh proof and approval; do not transfer a proven identity merely to clear a collision.
Run the workload and approve its registration
Section titled “Run the workload and approve its registration”- Open Agentic → Agents → Needs attention and select the
registration’s Review button. Check the stable workspace key, display
name, framework, and Accountable owner. When the developer ran the SDK
with
DEEPINTSHIELD_REGISTERED_BY, the header showsRegistered by <email>with Given by the developer with the virtual key. Not verified. The gateway mapped the address to a person in the workspace directory, created just in time when unknown, and proposes that person as the owner: select Confirm owner or choose another. The address is not verified and grants nothing. Without that setting, an e-mail-shapedrequesteris only an advisory hint: the header shows it only when it belongs to a person the organization placed in the workspace, and otherwise it is ignored, so the registration has no registering address. An enrolment policy’s owner takes precedence. If needed, Add owner → Name / Email → Create and select creates an active human directory entry without granting roles. - Select the validated Identity provider. A completed provisioning job has already declared the expected identity. For an externally provisioned workload without a declaration, enter its exact Expected identity and click Declare once. A friendly key differing from the provider’s child ID is expected; identity does not match can mean that declaration/proof is still missing.
- Check that Submission identity shows Active credential. The
developer needs four settings:
DEEPINTSHIELD_BASE_URL,DEEPINTSHIELD_VIRTUAL_KEY,DEEPINTSHIELD_AGENT_NAMEandDEEPINTSHIELD_REGISTERED_BY. Run setup → Copy settings under Runtime access supplies only the URL and the agent name; the developer supplies the active key through the workload’s secret manager and their own work e-mail. Run 1 of the saved script captures the source and, in Entra gateway mode, enrols the runtime key; the developer sees onlyRegistration pending. Reference <registration id> · runtime key SHA256:<thumbprint>. Contact your administrator. You will be notified at <email>.and receives no review link. The closing sentence appears only when the gateway confirmed the address. - In Runtime access, compare Key fingerprint with the thumbprint the
developer received and select Authorize runtime key. A key submitted
before its identity existed is marked Provisional with Runtime key
received. Create or link the agent identity in Step 1, then authorize this
key.; authorizing it before the identity exists is refused with
runtime_binding_identity_missing. For direct mode, the workload host itself must hold an Entra credential (environment variables, workload identity federation or a managed identity); the SDK obtains provider settings from the gateway and exchanges that host proof for the child token. See the SDK first-run example. - Proof arrives on the agent’s next run, not during the sitting. Workload
proof not observed / Awaiting workload proof is expected at this
point; with the identity declared and exactly one authorized key, Review &
decide offers Approve now, activates on the agent’s next run. A tested
provider, active reporting key, or completed provisioning job does not
satisfy the proof requirement; the next attested run does. Without deferred
activation, the developer runs again now and a run can still report
agent_registration_pendinguntil approval. - Open Code & changes to review the source scan, then Tools & access to review the exact tool
actions.
blueprint_coverage_incompleterequires complete executable-source capture from the saved workload with a current SDK. An empty artifact list is not a completed code review; identity, model, or permission changes cannot supply that evidence. See Blueprint code review. - Select only the observed tool actions and required resource permissions. A local workload with no tools needs no tool grant. Namespace and governed capabilities describe governance; they are not resource permissions. Reuse an access profile only after checking its proposed exact choices.
- When Owner, Identity, Code, and Access are ready and proof is still outstanding, select Approve now, activates on the agent’s next run and confirm with Approve now · activates on next run: the card shows Decision recorded and lists the actions that activation will grant, the developer is e-mailed, and the next run of the unchanged script activates the agent and executes it. The reviewer cannot be the accountable owner. Resource permissions, roles and delegations are not part of a recorded decision; add them after activation when the agent needs them. When proof has already been observed, choose Preview approval, inspect the proposed changes, then Confirm approval and access. If a saved plan reports access incomplete, use Resume saved approval to complete it. A changed or conflicting plan needs a fresh review; archiving a plan does not grant or revoke existing access. The Deny action requires a note; the developer is e-mailed either way.
The intended endpoint is Decision recorded followed by an approved run, or Approved. Selected access is ready. after an immediate approval. Run the same workload again with the same key and identity. Runtime policy, tool integrity, any on-behalf-of user’s permissions, and later code changes still apply. See Guided access.
Provider validation, workload authentication, and access approval have different owners. An administrator configures the provider and runtime credentials once. The reviewer then checks identity proof, code, ownership, and exact access in one registration review workspace. Provider validation does not prove that Python has the credentials, and clicking Declare does not authenticate it.
| Who and where | What to configure | When |
|---|---|---|
| Identity administrator, identity provider console | A workload application and the credential or federation it will use | Once per workload identity; update on rotation or deployment changes |
| Platform administrator, Agentic → Identities → Identity providers | Issuer, gateway audience, signing keys, and provider-specific settings; validate the provider | Once per provider configuration, then after configuration changes |
| Developer, machine/container running Python | Gateway URL, active virtual key from a secret manager, friendly agent name, work e-mail (DEEPINTSHIELD_REGISTERED_BY), and workload credentials for direct mode | Once per deployment |
| Reviewer, Agents → Needs attention → Review | Owner, expected identity if needed, authorized runtime key, completed code scan, exact tool/resource access; must not be the accountable owner for a deferred decision | Initial approval and changes that require review |
| SDK and gateway | Acquire/refresh tokens and check runtime authorization | Automatically during execution |
For Entra direct mode, the host credential must be trusted by the selected blueprint’s
federated identity configuration. Installing deepintshield[azure], signing in
to the dashboard, or declaring the child UUID does not create that trust. An SSH
tunnel to a gateway does not transfer an Azure host’s managed identity to a
Python process running on a laptop.
For Generic OIDC, configure the following separately:
| Location | Setting | Value |
|---|---|---|
| Provider editor | Issuer URL | Exact issuer from the identity provider’s discovery metadata |
| Provider editor | Audience (verify) | The API identifier in the access token’s aud; not automatically the browser URL |
| Provider editor | JWKS URI | Public signing-key URL, or leave blank and validate to discover and save it |
| Provider editor or workload environment | Client ID / OIDC_CLIENT_ID | The workload application’s client ID |
| Workload environment | OIDC_TOKEN_ENDPOINT | Provider-advertised token endpoint; the SDK can discover it from the issuer if omitted |
| Workload environment | OIDC_SCOPES | Space-separated per-client scopes; unset uses provider defaults and empty requests no scopes |
| Workload environment | OIDC_AUDIENCE | Token-request audience where required; empty omits it without changing gateway audience verification |
| Workload secret manager | OIDC_CLIENT_SECRET | The application secret for a secret-based client authentication method |
| Agent review | Expected identity | Token principal (normally sub); it need not equal the OAuth client ID |
Copy the provider’s principal exactly, including case and any literal agent:
prefix. Generic OIDC and ZeroID identities are case-sensitive. The server may
represent an opaque principal as an internal hashed identity key after
declaration; keep the friendly agent name in Python.
An older provider tested with an empty JWKS URI may need to be tested again once so the discovered URL is saved. The gateway reports this as a revalidation requirement. Discovery and provider tests belong to setup, not every tool call.
If an older bound Generic OIDC/ZeroID agent relied on case folding, prefix removal, or the earlier mapping of URI subjects, it needs a new reviewed registration under a unique agent key with the exact raw principal. A bound alias cannot be silently repointed. Approve the replacement’s required access, then retire the old registration. Ordinary lowercase principal IDs and Entra UUID bindings retain their existing mapping.
For another client authentication method, set OIDC_CLIENT_AUTH_METHOD on the
machine running Python. client_secret_basic uses the application secret;
private_key_jwt uses OIDC_PRIVATE_KEY_FILE (and optional key ID/algorithm);
tls_client_auth or self_signed_tls_client_auth uses OIDC_CLIENT_CERT_FILE
and OIDC_CLIENT_KEY_FILE. Register the corresponding public key or certificate
with the issuer first. Private files and passwords stay in the workload’s
secret manager. These TLS methods authenticate at the token endpoint; they do
not add support for certificate-bound access tokens at the gateway.
Use an access token intended for the gateway, not a browser ID token. OIDC login support alone does not guarantee an issuer supports the workload’s client credentials grant, token format, or chosen client authentication method.
Names and workspace isolation
Section titled “Names and workspace isolation”DEEPINTSHIELD_AGENT_NAME selects the agent key within its organization and
workspace. A different human using the same name does not create another agent.
An unassociated virtual key cannot take over an existing registration. Use a
different key name such as simple-math-agent-alice for an independent agent in
the same workspace; another workspace can reuse simple-math-agent with its own
registration. Display labels can repeat.
For a provider-backed agent, an associated virtual key must also present proof for the bound workload identity. Someone who possesses both authorized credentials is operating that same agent, subject to runtime permissions and code review. VK-trusted agents have no provider-backed authentication check.
Admit a class of identities from one provider
Section titled “Admit a class of identities from one provider”Binding a provider to exactly one client id means one provider row per agent, with
the same issuer, authority, and audience re-entered for every agent in the
estate. agent_identity_match_mode generalises that from “this one agent” to
“the agents this issuer vouches for”:
| Mode | Admits |
|---|---|
exact (default) | Only the configured agent identity client id. |
list | Any value in agent_identity_match. |
prefix | Any value carrying one of the listed prefixes. |
any | Any identity the issuer signs for. Correct only when the issuer is dedicated to this workspace’s agents. |
Per-agent binding is not weakened by this. Whatever the predicate admits, the
agent subject is still pinned to the exact identity the token carries. The
predicate decides which identities a provider may speak for, never which agent
a given token is. An unrecognised mode collapses to exact, so a typo can
never widen a provider.
Bound accepted token lifetime
Section titled “Bound accepted token lifetime”exp alone leaves the issuer deciding how long a stolen credential stays
useful: an issuer minting 24-hour agent tokens has every one of them honoured
for its full life, so a token lifted from a log or a crash dump is valid for
the rest of the day.
accepted_token_max_ttl_sec on the identity provider is the relying party’s
own tolerance:
| Value | Effect |
|---|---|
0 (default) | A bounded default of one hour. Accommodates the common one-hour token while removing the unbounded case. |
| n > 0 | Refuse a token from this provider whose total lifetime exceeds n seconds. |
| n < 0 | Disable the ceiling. An operator has to choose this deliberately. |
This is separate from token_max_ttl_sec, which is mint-side and only shortens
the expiry on tokens the gateway itself hands out.
Token lifetime is also separate from registration approval. An approved agent
has no fixed run count or registration expiry: subsequent actions still
require current credentials, grants, policy, and an accepted blueprint.
Provider-backed SDK credentials refresh on demand when renewal is needed;
StaticAgentCredential cannot renew a supplied token. A token expiring does
not itself delete the registration. See
Repeated runs.
Replay protection
Section titled “Replay protection”Bearer access tokens can be reused until expiry, including tokens containing
jti. Making those tokens single-use conflicts with normal SDK token caching
and is not sender authentication. Protect bearer credentials with TLS, limited
audiences and privileges, short lifetimes, and controlled secret handling.
For sender-constrained tokens, each request instead carries a fresh DPoP proof.
The proof’s jti is single-use and checked against shared durable storage across
gateway replicas. The access token remains reusable with a new valid proof;
reusing a proof is rejected, and replay-store failures fail closed.
Proof-of-possession (DPoP)
Section titled “Proof-of-possession (DPoP)”Set require_proof_of_possession on an identity provider to refuse a plain
bearer token from it. The client then holds a private key, the issuer binds
that key’s thumbprint into the token as cnf.jkt, and every request carries a
fresh proof signed by the key over the request method and URI
(RFC 9449). A stolen token
without the key is useless.
- It is off by default, and should stay off until the issuer actually binds
tokens. A token with no
cnf.jkthas nothing to prove possession of, so enabling this first denies everything. - Ordinary tokens without a
cnfclaim remain usable when proof of possession is optional. Malformed or unsupported confirmation constraints are refused; certificate-bound tokens are not silently treated as ordinary bearer tokens. - The Python SDK generates an ephemeral per-process key and needs the optional
dependency:
pip install "deepintshield[dpop]==3.2.0". See Agents and Agentic governance. - Automatic acquisition of issuer-bound tokens is supported by the Generic OIDC adapter when the issuer supports DPoP. The built-in Entra and ZeroID exchange adapters reject a required-DPoP configuration they cannot satisfy.
Protecting an approved binding
Section titled “Protecting an approved binding”Once an agent’s registration is approved with an identity provider, clearing
that provider is an attestation downgrade: the agent would keep every grant
it earned while proving less about who it is. PUT /agents/{id}/governance
therefore refuses to empty identity_provider_id on an approved agent;
changing it requires an explicit re-review.
Expected identities: the resolution layer
Section titled “Expected identities: the resolution layer”A workload often announces itself by a friendly name (agent:math-agent)
while the identity a provider can prove for it is a client id
(agent:11111111-…). An expected identity declares, per friendly agent key
and workspace, which provider-issued identity that name is expected to prove.
It is modelled on a SPIRE registration entry: it names the identity a workload
should attest to, and it never attests anything itself.
What a declaration does:
- Resolves the name before validation and verification. At first sighting,
a token that verifies against the declared provider and derives to exactly
the expected subject attests the registration under the friendly name. At
runtime, a bound agent’s token is verified as the expected identity while the
agent keeps its friendly subject - so every
allowed_callertuple, resource grant and delegation stays keyed toagent:<key>and survives the upgrade from VK-trusted to provider-attested. - Unlocks an explicit VK-trusted approval. With an expected identity declared, the review form offers Approve as VK-trusted (development only) while the workspace setting Allow VK-trusted approvals (development only) is on: the agent is approved with no provider, recorded as unattested, and carries its own exit - the declaration says what proof will complete it.
- Proposes, never promotes. When an approved VK-trusted agent later presents a verified token for exactly its expected identity, the gateway records an attestation upgrade proposal. The call proceeds VK-trusted and nothing on the agent changes until an operator confirms in the registration review. Confirmation binds the provider, records which provider attested the agent and when, and marks the declaration bound - in one transaction, under row locks, re-checking that the proposal still matches the declaration and that the provider is enabled and tested.
Invariants the layer enforces:
- A declaration can be satisfied only by a verified token for exactly the expected subject from exactly the expected provider. Selecting the expected provider in a review for a registration that never presented such a token is refused - declaring is not vouching.
- Proof applies to the current declaration. Changing the expected identity, including changing away and back, requires fresh proof. A note-only edit does not. Existing pending declarations from an older server may need one credentialed rerun after upgrading; approved profiles remain approved.
- One name, one identity; one identity, one name per workspace, enforced by the database. Two names can never race for the same credential.
- A bound declaration is immutable: re-pointing a name at another identity is an identity change and goes through registration review again. Deleting it is refused for the same reason.
- The resolved identity is stored on the agent profile the request already loads, so runtime resolution needs no additional declaration-table query.
In Agents → Needs attention, open Review on the discovered registration. Choose an enabled, tested Identity provider, enter Expected identity, and select Declare, or create or link the identity from the same sitting. This is an identity declaration only. With the runtime key authorized, record the decision with Approve now, activates on the agent’s next run: the decision binds to that declaration’s revision, and the agent’s next run must present matching verified proof before it activates. Changing the declaration afterwards marks the decision stale. Use Approve as VK-trusted (development only) only when the deployment deliberately accepts unattested trust in the reporting Virtual Key; it is offered only while the workspace allows it, labelled development-only, and cannot be deferred. It is a distinct trust mode, not a fix for missing workload proof.
When matching verified proof later arrives, the review shows Token verified · confirm identity. Select Confirm attestation to bind the provider while preserving the friendly agent subject and its grants. Declaring or observing the identity never silently performs that upgrade.
Manage declarations from the registration review (Expected identity) or the API:
GET /api/agentic-new/registry/identity-aliasesPUT /api/agentic-new/registry/identity-aliases {agent_key, expected_provider_id, expected_subject}DELETE /api/agentic-new/registry/identity-aliases/{id}POST /api/agentic-new/registry/registrations/{id}/attest confirm a verified proposalPOST /api/agentic-new/registry/registrations/{id}/attest/dismissNext steps
Section titled “Next steps”- Agent Enrolment: enrol a class of verified agents from one rule.
- Agentic: the full control-plane workflow.
- Registration notifications: the e-mails each registration step sends and the mailbox that sends them.
- Setting up Entra: connect Microsoft Entra.