Identity & OBO (enterprise)
Per-user identity — running each action as the signed-in human via SSO and on-behalf-of token exchange — is an Gnomus enterprise feature. The open-source edition is local-auth only. This page documents the enterprise identity architecture.
Open-source edition: local auth only. The self-hosted OpenAgentic edition authenticates with a local username/password account, JWTs, and API keys — there is no SSO, Azure AD / Entra, on-behalf-of (OBO), or MFA in OSS. Cloud MCP servers (AWS, Azure, GCP) authenticate with the static service-account credentials you configure, not a per-user identity. Everything below describes the per-user identity architecture in the Gnomus enterprise edition — see agenticwork.io. It is documented here as a reference for what regulated deployments are built toward, not as an OSS capability.
A privileged action taken by an AI agent should be attributable to the human who authorized it — not to a shared service account a dozen people quietly share. The enterprise identity model runs the agent as the Entra user: the human signs in once to Entra (Azure AD / Entra ID), and that identity federates down into every cloud and infrastructure plane the agent touches, using short-lived, per-user credentials instead of a standing key.
Why a shared key is a blind spot
Shared service accounts and long-lived access keys collapse N humans into one
machine identity. When the agent acts through a single role, the audit trail tells
you that OpenAgenticServiceRole did something — never that Alice did it. For a
high-impact system that is a finding, because it cuts against the control families
these systems are held to under NIST SP 800-53
and the FedRAMP High baseline:
- AC-2 (account management) — accounts should map to individuals, not a pool behind one key.
- AC-6 (least privilege) — rules out a broad standing grant every tool inherits.
- AU-2 / AU-12 (audit events) — each event must be attributable to a specific user.
- IA-2 (identification & authentication) — individual identification anchored in phishing-resistant MFA.
The model: on-behalf-of (OBO)
OBO means the agent exchanges the human’s own Entra access token for a short-lived, downstream credential scoped to that human — so the platform only ever has the access you hand it, never a standing key of its own. Entra is the identity provider; every downstream exchange starts from the user’s own token.
One detail matters end to end: it is the access token, not the id token, that STS, Azure ARM, and GCP IAM accept as the bearer. Credentials are minted per user, per session — least-privilege scoped, not one shared role for everyone.
Enterprise feature. This per-user OBO model is part of Gnomus enterprise edition, not the open-source build. The setup below uses standard vendor syntax (Entra app registration, AWS STS, GCP Workload Identity, Kubernetes OIDC); it is the identity architecture regulated enterprise deployments are built on. The self-hosted OSS edition uses static service-account credentials instead.
End to end, as the user — and the RBAC you already have
The requirement behind this model is auditability that doesn’t break: every action — chat, Flows, and every tool call in between — must resolve to the human who is logged in, not just the final cloud API call. Running as the Entra user is what keeps that chain continuous.
It also means the platform inherits the cloud RBAC already assigned to that identity — there is no second permission model to build and reconcile. What you can do and see in the platform is exactly what your identity is already allowed to do and see in the cloud, because the platform acts as that identity.
This maps onto how privileged access already works: operators commonly carry a
standard identity for day-to-day work and an elevated one — a privileged / JIT
admin role, the directory equivalent of sudo. Which identity you sign into the
platform as determines what you can do and see — standard login, standard scope;
elevated login, elevated scope — exactly as if you had logged into the Azure portal, the
AWS console, or gcloud directly as that user. The platform’s audit log and each cloud’s
native log then name the same human, at the privilege level they signed in with.
Setting it up
Every block below is standard vendor syntax. The only OpenAgentic-specific values
are the two environment variables the AWS module reads (AWS_OBO_ROLE_ARN /
AWS_ACCOUNT_ID).
1. Register the Entra app + expose the OBO scope
In Entra ID under App registrations, create (or reuse) the OpenAgentic app and
note its Application (client) ID and Directory (tenant) ID. Under Expose an
API, set the Application ID URI (e.g. api://<client-id>) and add a delegated
scope (e.g. access_as_user) — the scope the agent requests on the user’s behalf.
Under API permissions, add the delegated downstream permissions, then grant
tenant admin consent.
The OBO grant uses grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer with
requested_token_use=on_behalf_of against the v2.0 /token endpoint — see
Microsoft’s on-behalf-of flow docs.
2. AWS — trust Entra at IAM Identity Center / STS
Federate Entra into AWS via (a) SAML / OIDC into IAM Identity Center, or (b) a direct OIDC identity provider in IAM for the token-to-STS exchange. For the run-as-user path, create an IAM role whose trust policy trusts the Entra OIDC issuer and constrains the audience:
{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::<account-id>:oidc-provider/login.microsoftonline.com/<tenant-id>/v2.0" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "login.microsoftonline.com/<tenant-id>/v2.0:aud": "<entra-client-id>" }} }]}Attach a least-privilege permission policy — only what the agent’s tools need — then
point OpenAgentic at the role. The AWS OIDC federation module resolves the role ARN
from an explicit roleArn option, AWS_OBO_ROLE_ARN (full ARN), or AWS_ACCOUNT_ID
(from which it builds arn:aws:iam::<account>:role/OpenAgenticOBORole):
export AWS_OBO_ROLE_ARN="arn:aws:iam::123456789012:role/OpenAgenticOBORole"# or: export AWS_ACCOUNT_ID="123456789012"At call time the platform runs AssumeRoleWithWebIdentity with the user’s Entra
access token as the WebIdentityToken and a RoleSessionName derived from the user’s
email (sanitized, capped at 32 chars) — so CloudTrail records the human. The
credentials are short-lived (one hour by default, with a 60-second safety buffer).
3. GCP — Workload Identity Federation pool + provider
gcloud iam workload-identity-pools create openagentic-pool \ --location=global --display-name="OpenAgentic Entra"
gcloud iam workload-identity-pools providers create-oidc entra \ --location=global --workload-identity-pool=openagentic-pool \ --issuer-uri="https://login.microsoftonline.com/<tenant-id>/v2.0" \ --allowed-audiences="<entra-client-id>" \ --attribute-mapping="google.subject=assertion.sub,attribute.email=assertion.email"Bind the federated principal to least-privilege roles, optionally via service-account impersonation:
gcloud iam service-accounts add-iam-policy-binding <sa>@<project>.iam.gserviceaccount.com \ --role=roles/iam.workloadIdentityUser \ --member="principal://iam.googleapis.com/projects/<num>/locations/global/workloadIdentityPools/openagentic-pool/subject/<entra-subject>"The platform exchanges the Entra OIDC token for short-lived Google credentials, and Cloud Audit Logs attribute the human — see the Workload Identity Federation docs. Today the Vertex auth reads Application Default Credentials / Workload Identity on a GCP node; the per-user Entra token exchange above is the path the architecture is built for.
4. Kubernetes — API-server OIDC + a ClusterRoleBinding
Configure the API server to trust Entra as an OIDC issuer (AKS exposes this natively; on EKS/GKE you supply an OIDC issuer config):
--oidc-issuer-url=https://login.microsoftonline.com/<tenant-id>/v2.0--oidc-client-id=<entra-client-id>--oidc-username-claim=email--oidc-groups-claim=groupsThen bind the Entra group (or a specific user oid) to RBAC:
apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: name: openagentic-operatorsroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: edit # least-privilege built-in or a custom Rolesubjects:- apiGroup: rbac.authorization.k8s.io kind: Group name: "<entra-group-object-id>" # Entra group GUID from the groups claimWith OIDC plus this binding, kubectl and agent calls authenticate as the Entra
user, and the Kubernetes audit log records the individual — see the
Kubernetes OIDC docs.
What it buys you
CloudTrail (AWS), Cloud Audit Logs (GCP), and the Kubernetes audit log all name the individual, never a shared robot. AC-6 is met by short-lived, least-privilege credentials; AU-2 / AU-12 by per-user attribution in each plane’s native log; and IA-2 by anchoring identity in Entra’s phishing-resistant MFA.
OpenAgentic’s own audit layer closes the loop: every agent tool call is written to an
append-only agent_audit_log (each action_type — tool_call, llm_completion,
delegation, approval, data_access — keyed to the acting user_id), the admin
event trail is tamper-evident via per-row hash chaining, and mutating tool calls pass
through an approval gate first. When the tool executes as the Entra user, the
internal record and the cloud’s native log agree on one name — the human.
OSS vs. enterprise: the identity seam
The split between the self-hosted build and enterprise sits at the identity source. What changes is whether the platform anchors to a per-user identity provider at all, and how cloud MCP credentials are obtained.
| Identity | Self-hosted (OSS) | Enterprise |
|---|---|---|
| Auth | Local username/password + JWT + API keys — no SSO/AAD/Entra/OBO/MFA | SSO / directory integration (Entra/AAD, AWS IAM Identity Center, Google Workspace) + MFA |
| Cloud MCP creds | Static service-account credentials you configure per cloud | Per-user OBO across the supported IdPs |
| Attribution | The configured service identity | Per-user OBO — the human in every log |
To be straight about the self-hosted build: it is local-auth only. The cloud
MCP servers (openagentic_aws, openagentic_azure, openagentic_gcp)
authenticate with static service-account credentials — the OSS edition does not
perform per-user OBO. The entire per-user identity model on this page is the
Gnomus enterprise layer. See MCP servers and
Configuration for the OSS credential model.
Compliance framing
Federal, healthcare, defense, and regulated industries are the environments this identity architecture is built for. To be exact: this describes a capability and a design intent, not a certification. Compliance is a property of a specific deployment and its authorizing body — not of software in the abstract. The architecture is built to meet and architected to satisfy FedRAMP High and NIST 800-53 high-impact identity and audit controls; it does not carry an authorization, and no deployment is implied here.