openagentics

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):

Terminal window
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

Terminal window
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:

Terminal window
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=groups

Then bind the Entra group (or a specific user oid) to RBAC:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: openagentic-operators
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: edit # least-privilege built-in or a custom Role
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: "<entra-group-object-id>" # Entra group GUID from the groups claim

With 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_typetool_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.

IdentitySelf-hosted (OSS)Enterprise
AuthLocal username/password + JWT + API keys — no SSO/AAD/Entra/OBO/MFASSO / directory integration (Entra/AAD, AWS IAM Identity Center, Google Workspace) + MFA
Cloud MCP credsStatic service-account credentials you configure per cloudPer-user OBO across the supported IdPs
AttributionThe configured service identityPer-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.