Bring your own IdP (Logto / OIDC)
PaloNexus governs agent egress with cryptographic agent identity (Decentralized Identifier / Verifiable Credential, DID/VC) that does not depend on the workforce identity provider (IdP) — egress works out of the box. This page is for the other identity seam: human workforce sign-in (the people who own agents, approve elevations, and operate the portal). The self-host overlay ships anonymous-passthrough by default; this runbook wires the organization’s IdP so the control plane verifies inbound human identity against that issuer.
Logto is the supported IdP — the worked example below. Okta, Entra ID, Auth0,
Keycloak, and any standard OpenID Connect (OIDC) provider integrate through the same three env vars and
the same SCIM (System for Cross-domain Identity Management) /v1/directory seam; only the issuer URLs differ. Shipped connectors for
the others are near-term roadmap, not a limitation of the standards path.
What the IdP must provide
Section titled “What the IdP must provide”Three public URLs + one audience. For Logto (tenant YOUR-TENANT):
| Value | Env var | Logto example |
|---|---|---|
| Issuer | OIDC_ISSUER | https://YOUR-TENANT.logto.app/oidc |
| JWKS | OIDC_JWKS_URL | https://YOUR-TENANT.logto.app/oidc/jwks |
| Audience | OIDC_AUDIENCE | palonexus (the registered API resource indicator) |
These are not secrets (public discovery URLs) — they live in a Kustomize component, not a Secret.
Step 1 — register PaloNexus in Logto (fresh tenant)
Section titled “Step 1 — register PaloNexus in Logto (fresh tenant)”- Create an API resource named e.g.
PaloNexuswith API identifierpalonexus. This identifier is theOIDC_AUDIENCE— access tokens must carry it asaud. - Create an application for the human sign-in surface (the portal / the SSO front
door). Note its issuer is the tenant’s
/oidcendpoint above. - Grab the issuer and JWKS (JSON Web Key Set) URLs from the tenant’s OIDC discovery
(
https://YOUR-TENANT.logto.app/oidc/.well-known/openid-configuration).
Any OIDC IdP: register an app + an API/audience, then read
issuerandjwks_urifrom that provider’s/.well-known/openid-configuration. Okta/Entra/Auth0/Keycloak all expose it.
Step 2 — enable the oidc Kustomize component
Section titled “Step 2 — enable the oidc Kustomize component”The self-host overlay strips the built-in Dex OIDC vars (anonymous-passthrough). To point at
the organization’s issuer, enable the oidc component and remove the strip patch (they conflict —
the component sets the vars the strip patch removes):
In deploy/kustomize/overlays/selfhost/kustomization.yaml:
- Under
components:, uncomment- ../../components/oidc. - In
patches:, delete the threeop: remove … /env/0lines (the anonymous-passthrough patch). The component re-adds OIDC; leaving the strip would undo it.
Set the issuer values by editing deploy/kustomize/components/oidc/kustomization.yaml
(replace YOUR-TENANT.logto.app and the audience). Render to confirm:
make render-selfhost | grep -A1 OIDC_ISSUER # shows the configured issuer + jwks + audienceApply (or make install-selfhost):
kubectl apply -k deploy/kustomize/overlays/selfhost --load-restrictor LoadRestrictionsNonekubectl -n palonexus rollout status deploy/control-planeThe control plane now verifies inbound bearer JSON Web Tokens (JWTs) against the IdP’s JWKS, requiring
iss == OIDC_ISSUER and OIDC_AUDIENCE ∈ aud. A token from the configured IdP is accepted; anything
else is denied (fail-closed). Egress decisions are unchanged.
Step 3 — push the workforce directory (SCIM / API)
Section titled “Step 3 — push the workforce directory (SCIM / API)”Human ownership, approval authority, and the revocation cascade key off a stable directory subject (not email). Feed the workforce directory into agent-idp’s directory seam so those subjects resolve:
# Full-snapshot reconcile (the supported model — joiner/mover/leaver):curl -sS -X POST "$AGENT_IDP_URL/v1/directory/sync" \ -H 'content-type: application/json' \ -d @your-directory-snapshot.jsonThe snapshot maps each employee to a stable employeeId subject + org/group membership; a
leaver in a later snapshot triggers the revocation cascade (agents owned by that subject lose
their delegations). See Connect agents to enterprise authority for the schema. A
turnkey vendor SCIM connector (Logto/Okta push) is near-term roadmap; today the snapshot is
pushed from the directory of record (the seeder in seed-logto/ is the worked example for
Logto, and a template for any source).
Step 4 — verify
Section titled “Step 4 — verify”# A human token from the configured IdP resolves to a stable subject:curl -sS -X POST "$AGENT_IDP_URL/v1/identity/resolve" \ -H 'content-type: application/json' -d '{"token":"<a real login JWT from your IdP>"}'# -> {"subject":"NST-1011", "source":"scim", ...} (not "unresolved")
# An inbound call with that token is accepted at /authz; without it, denied.Acceptance: a real login token from the configured IdP is verified at /authz (right iss/aud),
resolves to a stable workforce subject via /v1/identity/resolve, and that subject can own
agents / approve elevations in the portal. Removing the component (or supplying a token from a
different issuer) fails closed.
Notes & limits
Section titled “Notes & limits”- Logto is the supported IdP (worked example + seeder). Other OIDC IdPs use the identical three-env-var + SCIM-snapshot path; shipped vendor connectors are roadmap (BACKLOG → Deferred IdP Integrations).
- Real JWT/JWKS verification is enforced at the control-plane edge;
/v1/identity/resolveMVP trusts decoded claims from that verified edge (see the IdP-support concept page). - Docker Compose has its own OIDC turn-on (3 env vars in
.env); see Docker Compose. This page is the Kubernetes equivalent.