Skip to content

Architecture

Packages

.
├── packages/
│   ├── api/          # Backend API (Express + TypeScript) — the management API and the
│   │                 # emulated OIDC/pi.flow engine
│   ├── admin-ui/      # Admin Portal (React + Vite) — manage organizations platform-wide
│   ├── org-ui/        # Organization Portal (React + Vite) — an organization manages its own
│   │                 # environments
│   ├── mcp/           # Read-only MCP server exposing the API to Claude Code / Claude Desktop
│   ├── agent/         # Mastra-based conversational CLI built on packages/mcp
│   └── pf-signon-ui/  # A PingFederate-style / PingOne-style sign-on demo UI

packages/api is a Postgres + Prisma backend. Some migrations are hand-written SQL rather than Prisma-generated: the dev database is shared with other services, so a schema-diffing Prisma command can propose dropping tables that don't belong to this project at all.

Two API surfaces

The management API (/v1/...) — environments, applications, populations, sign-on policies, identity providers, DaVinci flows, schemas, gateways, and more. Shaped to match the PingOne Terraform provider so real pingone_* Terraform resources work against it unmodified — this is what every terraform/* module in this repo provisions against.

The emulated OIDC/authorize surface (/:environmentId/as/authorize, /:environmentId/flows/:id, /:environmentId/token, etc.) — the actual sign-on experience: pi.flow interactive authentication, token issuance, and OAuth2 client authentication. See The pi.flow Protocol.

Pluggable auth-flow providers

Every environment picks which engine handles its own authorize/flows/token calls, via metadata.authProvider on the pingone_environment resource (packages/api/src/lib/authFlow/):

  • emulated (the default) — a fully in-house implementation of the pi.flow protocol (emulatedProvider.ts): username/password, self-registration, MFA, and WebAuthn/passkey ceremonies, all real working state machines rather than static mocks.
  • pingfederate — delegates to a real PingFederate instance (pingFederateProvider.ts) running in this environment's own Docker setup, for cases where the real product's behavior matters more than a fast, dependency-free emulation.

Both implement the same AuthorizationFlowProvider interface (packages/api/src/lib/authFlow/types.ts), so callers (routes/v1/token.ts, routes/v1/flows.ts) never branch on which engine is active — getAuthorizationFlowProvider(environmentId) resolves it once per call and both are transparently wrapped with audit logging (packages/api/src/lib/auditStore/).

Real backing services, not just mocks

Where the real product's own behavior is what matters, this repo runs the real thing rather than reimplementing it: PingFederate and PingDirectory containers back specific environments and capabilities (see .pingfederate/, .pingdirectory/ — both gitignored, local container provisioning state). This is why some setup docs talk about "server profiles" and container provisioning rather than pure application config.

DaVinci flows

packages/api/src/lib/davinci/ handles DaVinci-flow-shaped configuration — flows are modeled as a graph (graphToFlowDefinition.ts) and can be synced against a real flow-execution engine (authrFlowSync.ts) in the separate atlassian-adf-form-r repo, which hosts the actual DaVinci Hosted Login experience for flow-driven demos.

MCP server and agent

packages/mcp is a read-only MCP server exposing the management API as tools (environments, applications, users, sign-on policies, DaVinci flows, token introspection, a monitoring summary, and a generic api_get escape hatch), intended for conversational dev/ops introspection from Claude Code or Claude Desktop. packages/agent is a Mastra-based CLI that talks to a running instance through those same MCP tools. Both are read-only by construction: only read tools exist, the underlying HTTP client has no write method, and the recommended credential is a seeded viewer account the API's own organizationAdminMiddleware would 403 on any write regardless.