@idp.global/app
Identity infrastructure for apps that need accounts, sessions, organizations, invites, admin tooling, mobile passport approvals, security alerts, OpenID Connect, SAML SSO, and SCIM in one TypeScript codebase.
This repository ships the idp.global server, CLI, and web UI used by the hosted service. Shared public contracts live in @idp.global/interfaces; reusable browser/server SDK code lives in @idp.global/sdk.
Issue Reporting and Security
For reporting bugs, issues, or security vulnerabilities, please visit community.foss.global/. This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a code.foss.global/ account to submit Pull Requests directly.
What It Does
- Runs an identity provider with MongoDB-backed users, sessions, roles, organizations, invitations, OIDC clients, and billing plans.
- Serves a web app for login, registration, account management, org management, billing flows, and global admin views.
- Exposes typed realtime APIs over
typedrequestandtypedsocket. - Implements OIDC/OAuth endpoints including discovery, JWKS, authorization, token, userinfo, and revoke.
- Provides inbound SAML SSO with DNS-verified organization domains, JIT provisioning, group-to-role mapping, and SCIM 2.0 provisioning.
- Supports passport-style mobile device enrollment, signed approval challenges, push registration, security alerts, and NFC/location-backed identity proof flows.
- Includes a reusable browser client and a terminal CLI for common account and org workflows.
Monorepo Modules
| Folder | Purpose |
|---|---|
ts/ |
Backend service entrypoint and the core Reception managers |
ts_idpcli/ |
CLI published as @idp.global/cli |
ts_web/ |
Frontend bundle with login, registration, account, org, billing, and admin views |
../interfaces/ |
Shared request and data contracts published as @idp.global/interfaces |
../sdk/ |
Browser and server SDK published as @idp.global/sdk |
Core Backend Pieces
Reception wires the service together and starts these managers:
JwtManagerfor signing, refreshing, and validating JWTs.LoginSessionManagerfor login state and session lifecycle.RegistrationSessionManagerfor multi-step sign-up flows.UserManagerfor user lookups and account data.OrganizationManagerfor org creation and membership lookup.RoleManagerfor org roles and permissions.UserInvitationManagerfor invites, membership updates, and ownership transfer.BillingPlanManagerfor Paddle-backed billing data.AppManagerandAppConnectionManagerfor app connections and admin app stats.AuditManagerfor privacy-safe structured events, integrity verification, and durable append-only sink delivery.AlertManagerfor passport alerts and organization/global alert rules.AbuseProtectionManagerfor keyed, owner-fenced rate limits on login, recovery, MFA, and OIDC token exchange flows.PassportManagerandPassportPushManagerfor trusted device enrollment, challenge approval, and push notification delivery.OidcManagerfor the OIDC/OAuth provider surface.EnterpriseSsoManagerfor SAML metadata, login, assertion validation, DNS domain ownership, and JIT provisioning.ScimManagerfor org-scoped SCIM users, groups, and bearer-token management.
Quick Start
Prerequisites
- Node.js 22.22.1
- pnpm 11.18.0
- MongoDB
Install
pnpm install
Required Environment
export MONGODB_URL=mongodb://localhost:27017/idp-dev
export IDP_ENV=local
export IDP_BASEURL=http://localhost:2999
export INSTANCE_NAME=idp-dev
export SERVEZONE_PLATFORM_AUTHORIZATION=test
export IDP_TOTP_ENCRYPTION_KEY=replace-with-at-least-32-characters
Startup validates a canonical runtime config before Reception starts. IDP_ENV accepts production, development, test, or local; any other value is rejected. When IDP_ENV is unset, the app defaults to production behavior.
IDP_BASEURL is the canonical public URL for OIDC issuer metadata and generated registration, login, password-reset, welcome, and invitation links. Production requires HTTPS. Local HTTP is only accepted with explicit IDP_ENV=local, development, or test, and only for localhost-style hostnames.
IDP_LOGIN_BASEURL, IDP_APP_BASEURL, and IDP_SUPERADMIN_BASEURL select the login, customer-console, and private global-administration surfaces. Outside production they are optional and default to IDP_BASEURL, so a single local origin serves every surface. In production all three are required, and the four configured origins must resolve to four distinct hostnames; startup rejects the configuration otherwise. Each value must be a credential-free origin URL — no path, query, fragment, or userinfo — and follows the same transport rule as IDP_BASEURL: HTTPS in production, localhost-style HTTP only in non-production modes. The four origins together form the WebAuthn allowed-origins set.
SERVEZONE_PLATFORM_AUTHORIZATION is required. The literal value test switches the platform client to debug mode for local development and tests and is rejected in production.
IDP_TOTP_ENCRYPTION_KEY is required in every runtime mode and must be at least 32 characters.
Production-required backend service token:
IDP_BACKEND_TOKEN— shared secret authenticating backend services on thegetPublicKeysForValidationandpushOrGetJwtIdBlocklisttyped endpoints. It is production-required and must be at least 32 characters. In non-production it can be omitted, and those endpoints remain fail-closed.
Optional:
PADDLE_TOKENPADDLE_PRICE_ID
Build
pnpm build
Run Locally
pnpm watch
This starts the backend watcher from ts/ and rebuilds the frontend bundle from ts_web/. The packaged executable constructs the production structured-audit runtime from environment configuration and fails closed unless OpenBao custody, Lossless object-storage retention, and the serve.zone dead-letter route all qualify. Tests inject the deterministic in-memory runtime explicitly. Do not use that test runtime for shared or production deployments.
Seed Development Data
pnpm run seed
The seed command starts an interactive CLI that writes to the configured local database. The default demo workspace creates a global admin, an organization, demo users, and global OAuth app records.
This seed path is development-only. Never run it against a production database; production first launch uses the explicit bootstrap described below and creates no demo records.
Default development credentials if accepted unchanged:
- Email:
admin@idp.global - Password:
idp.global
Those credentials are for disposable local instances only. Never reuse them for production or any shared environment.
Runtime Surface
Web Routes
| Route | Purpose |
|---|---|
/ |
Welcome page |
/login |
Login flow |
/logout |
Logout flow |
/register |
Registration flow |
/finishregistration |
Multi-step registration completion |
/dash |
Signed-in account area and account subroutes |
OIDC and OAuth Endpoints
| Route | Purpose |
|---|---|
/.well-known/openid-configuration |
Discovery document |
/.well-known/jwks.json |
Public signing keys |
/oauth/authorize |
Authorization endpoint |
/oauth/token |
Token exchange |
/oauth/userinfo |
UserInfo endpoint |
/oauth/revoke |
Token revocation |
Supported scopes in the OIDC manager include openid, profile, email, organizations, and roles.
When authorization reaches a first-time user, the login and registration surfaces preserve the server-side OIDC authorization transaction through email verification and account setup. The browser carries only its canonical opaque identifier in same-origin /login and /register links; the identifier is never placed in registration email links. Registration start requires the transaction to still be pending, proof responses return the transaction stored with that registration session, and a mismatch or malformed value is rejected rather than rebound.
Runtime OIDC Client Registration
Besides the passkey-guarded typed admin API used by the dashboard, two runtime surfaces can register global OIDC clients without a browser session.
Machine endpoint: POST /machine/v1/oidc-clients (issuer host)
Bearer-authenticated with an organization service-principal token, exactly like SCIM: no session is created or consulted, and the human strong-MFA step-up is inapplicable rather than skipped. Authorization is evidence-based: the principal must carry a capability from the closed service.* namespace, and every hostname it claims — each redirectUris and postLogoutRedirectUris entry plus the appUrl — must sit under a domain the principal's organization has proven through an unrevoked, verified DNS TXT ownership proof. Unproven domains are refused, and the organization mutation fence is held so a tenant cannot gain a client mid-teardown.
The JSON body carries name, appUrl, category, clientType (public or confidential), redirectUris, allowedScopes, and grantTypes, plus optional description, logoUrl, postLogoutRedirectUris, and oidcSettings. Confidential clients additionally require a caller-stable operationId and a secretDelivery envelope (RSA-3072/RSA-4096 OAEP-SHA-256 public key), the same one-time encrypted secret-delivery ceremony as the web path; no response ever contains a plaintext secret. Success returns 201 with the serialized app and, for confidential clients, the delivery receipt. The created record carries the creator reference non-user:service-principal:<id>, and the creation is recorded as an integrity-chained oidc_client_created audit event attributed to the service principal.
Runtime administrator CLI: node cli.js oidc-client-create
An in-process command on the server's own runtime (operators and agents reach it via cloudly deploymentWorkspaceExec). Possession of the runtime environment — the same strict env contract the server boots with, including MONGODB_URL and the audit-runtime credentials — is the authorization: no network login, no session, no passkey. Two fail-closed gates run before any write:
- The installed schema manifest digest must exactly match this build (
CurrentSchemaManager.assertCompleteInstalledSchema, verification only — the CLI never installs or repairs anything). - The initial-bootstrap receipt must be complete: the CLI refuses to mint clients before a human has bootstrapped the administrator account and organization, keeping the two-phase trust model enforced rather than assumed.
node cli.js oidc-client-create \
--name "My Service" --app-url https://service.example.com --category productivity \
--redirect-uri https://service.example.com/callback \
--scopes openid,profile,email \
--grant-types authorization_code,refresh_token \
--operation-id my-service-initial-client
Required flags: --name, --app-url, --category, --scopes (CSV of openid,profile,email,organizations,roles), --grant-types (CSV of authorization_code,refresh_token), --operation-id (caller-stable idempotency key). The authorization_code grant additionally requires at least one --redirect-uri (repeatable, exact HTTPS) and the openid scope, and refresh_token requires authorization_code. Optional: repeatable --post-logout-redirect-uri, --description, --logo-url, --access-token-lifetime/--id-token-lifetime/--refresh-token-lifetime (seconds), and --created-by-user-id to attribute ownership to a validated live global administrator. Only --client-type confidential (the default) is supported.
Output is exactly one JSON object on stdout; all other process output is rerouted to stderr. The client secret prints once, at creation, and is never recoverable — an idempotent retry with the same operation id returns clientSecret: null and points at rotation, while reusing an operation id with different parameters fails closed. The created record carries the creator reference non-user:runtime-admin-cli, a local-runtime-stdout delivery receipt with status delivered-local, and a system-actor oidc_client_created audit event on the internal-only channel.
Local Development IdP runtime protocol
node cli.js devidp-runtime --manifest <absolute-json> --result <absolute-json> is the app-owned machine protocol consumed by a separate local-development facade. It is not a seed command or a shared-development deployment mode. The app owns validation, deterministic provisioning, readiness, and result publication. The facade owns Docker and network lifecycle, Caddy/TLS and loopback-port exposure, protected input-file creation, the namespace-derived MongoDB container alias, command invocation, and cleanup. The command refuses production, requires serve.zone test authorization, forbids initial bootstrap, binds an isolated namespace-derived MongoDB database, validates every input before constructing the server or listener, and writes nothing to stdout.
The facade must launch the command with this runtime environment:
IDP_ENVis explicitlydevelopment,test, orlocal.IDP_BASEURL,IDP_LOGIN_BASEURL,IDP_APP_BASEURL, andIDP_SUPERADMIN_BASEURLexactly equal the four manifest origins. Those values also establish the exact WebAuthn allowed-origin set.MONGODB_URLtargets the manifest namespace's derived database using either its derived container alias on port27017or the bounded credential-free loopback form described below.SERVEZONE_PLATFORM_AUTHORIZATIONis exactlytest.- Every
IDP_INITIAL_BOOTSTRAP_*variable is absent. INSTANCE_NAMEandIDP_TOTP_ENCRYPTION_KEYsatisfy the normal runtime contract. The intended production-parity facade also supplies an independentIDP_OIDC_TRANSACTION_KEYand setsIDP_OPAQUE_OIDC_HANDOFF_ENABLED=true.
The generic Quick Start environment is not valid for this command: one shared HTTP origin or a non-derived database is rejected. Secret values belong in the process environment or protected mounted files as required by the normal runtime contract; they do not belong in the manifest or result.
The manifest is strict schema version 1; unknown or missing fields are rejected:
{
"schemaVersion": 1,
"namespace": "freelance-local",
"origins": {
"issuer": "https://idp.localhost:8443",
"login": "https://login.idp.localhost:8443",
"app": "https://app.idp.localhost:8443",
"superadmin": "https://superadmin.idp.localhost:8443"
},
"rpClient": {
"name": "freelance.global local development",
"appUrl": "https://localhost:8443/",
"redirectUris": ["https://localhost:8443/auth/callback"],
"postLogoutRedirectUris": ["https://localhost:8443/"],
"clientSecretFile": "/absolute/protected/client-secret"
},
"auditProtectorSecretFile": "/absolute/protected/audit-secret",
"personas": [
{
"name": "testuser",
"subject": "derived",
"email": "testuser@idp.localhost",
"displayName": "Test User",
"passwordFile": "/absolute/protected/testuser-password"
},
{
"name": "testmoderator",
"subject": "derived",
"email": "testmoderator@idp.localhost",
"displayName": "Test Moderator",
"passwordFile": "/absolute/protected/testmoderator-password"
},
{
"name": "testsuperadmin",
"subject": "derived",
"email": "testsuperadmin@idp.localhost",
"displayName": "Test Superadmin Persona",
"passwordFile": "/absolute/protected/testsuperadmin-password"
}
]
}
All four origins must be distinct canonical HTTPS origins with the exact hostnames shown and one shared explicit port. Client URLs are canonical, credential-free, fragment-free, exact HTTPS URLs; wildcards are forbidden. Every raw persona subject must be the literal sentinel derived; a concrete caller-supplied subject is rejected, and the app derives the persisted and result subject from the namespace and persona name. The three persona names are labels for downstream tests only: every provisioned identity is an ordinary active account with no global authority, direct capability, organization membership, or role.
The client secret, audit-protector secret, and three password files must be five distinct absolute regular files. Leaf symlinks, files writable by group or others, invalid UTF-8, control characters, read-time file changes, duplicate paths, and hard-link aliases are rejected. Secrets are never accepted in the manifest and their contents are excluded from its canonical SHA-256. The stable audit secret is required on every restart; shutdown clears the protector and receipt keys, while the stateless authenticated ephemeral audit providers retain no event or dead-letter maps and remain explicitly reported as degraded together with the serve.zone test platform.
The namespace digest is SHA-256("idp.global/devidp/namespace/v1\0" + namespace). The MongoDB database is idp_devidp_ plus its first 24 hexadecimal characters. The facade-created container alias is devidp-mongo- plus its first 12 hexadecimal characters and must use port 27017; focused host tests may instead use a credential-free explicit-port localhost, 127.0.0.1, or [::1] target. mongodb+srv, host lists, Unix sockets, arbitrary hosts, implicit ports, and a different database name are refused.
After Reception.start(), the runtime creates or exactly replays one confidential authorization-code/PKCE client and the three deterministic personas. Every record carries an immutable namespace receipt. An existing deterministic id, email, subject, client id, metadata, secret hash, receipt, private state, global authority, or role that does not match fails closed; unrelated sessions, consents, tokens, and audit history are not runtime-owned and do not block replay. Credentials are verified on replay and never rotated.
After provisioning, the result is published as a mode-0600 same-directory file using exclusive creation, full write, file sync, and an atomic hard link. Only successful publication permits the runtime to mark itself ready. The app retains the published inode identity until that transition; cancellation, a mark-ready failure, or any post-link publication failure removes and directory-syncs only that invocation-owned inode. It never renames over, removes, or modifies a foreign result, including a race winner. The exact result schema is:
{
"schemaVersion": 1,
"namespace": "freelance-local",
"manifestSha256": "<64 lowercase hexadecimal characters>",
"ready": true,
"status": "ready",
"origins": {
"issuer": "https://idp.localhost:8443",
"login": "https://login.idp.localhost:8443",
"app": "https://app.idp.localhost:8443",
"superadmin": "https://superadmin.idp.localhost:8443"
},
"clientId": "devidp-client-<derived>",
"personas": [
{ "name": "testuser", "subject": "devidp-user-<derived>" },
{ "name": "testmoderator", "subject": "devidp-user-<derived>" },
{ "name": "testsuperadmin", "subject": "devidp-user-<derived>" }
],
"internalPort": 2999,
"degraded": {
"audit": "ephemeral-memory",
"platform": "test-authorization"
}
}
SAML SSO And SCIM
| Route | Purpose |
|---|---|
/saml/login/:connectionId |
Start an SP-initiated SAML login for a connection with a verified domain |
/saml/acs/:connectionId |
Validate the signed SAML response and complete account linking or JIT provisioning |
/saml/sp/metadata/:connectionId |
Publish service-provider metadata for customer IdPs |
/scim/v2/* |
Org-scoped SCIM 2.0 discovery, user, and group endpoints |
Organization admins configure SAML and SCIM under the SSO & Provisioning view. Every SSO email domain starts pending with a generated DNS TXT challenge. Home-realm discovery, SAML login, existing-account linking, and JIT provisioning remain disabled for that domain until the authoritative claim is verified. Domain claims are globally unique across organizations.
The implemented SCIM profile is deliberately bounded:
| Capability | Declared support |
|---|---|
| Authentication and tenancy | Organization-scoped bearer tokens; every resource lookup and mutation is fenced to the token organization |
| Discovery | ServiceProviderConfig, ResourceTypes, and Schemas |
| Users | Create, retrieve, list, replace, patch, and deprovision; deactivated users remain retrievable |
| Groups | Create, retrieve, list, replace, patch membership, and delete |
| Filters | Equality only: users accept userName, emails.value, externalId, and id; groups accept displayName, externalId, and id |
| Pagination | One-based, default 100, maximum 200, stable database ordering; count=0 returns counts without resources |
| Versioning | Weak ETags in the HTTP ETag header and resource meta.version; single-resource GET supports If-None-Match/304, and PUT, PATCH, and DELETE accept optional If-Match/412 preconditions |
| PATCH compatibility | Case-insensitive operations, Entra boolean strings and no-path dotted user attributes, plus Okta/Entra group-member add, replace, and value-path removal |
| Conflicts | Per-organization user name/email, group display name, and external-ID uniqueness return SCIM 409 errors |
| Not supported | Bulk, sorting, password change, POST search, arbitrary filter grammar, or undeclared PATCH behavior |
Lists use explicitly hinted compound indexes that support their stable sort,
database pagination, and batched user/member projection reads. Real-Mongo
coverage seeds 320 users, groups, memberships, and tokens per tenant; first-page
document reads are bounded by the requested page size, member expansion uses
one link batch plus one user batch, token hashes resolve through one indexed
document, and organization token reads remain tenant-scoped. Production scale
and interoperability qualification still require the exact pinned Corestore
digest plus the Okta and Entra evidence in readme.plan.md.
SCIM bearer-token records use a globally unique token-hash authority, exact revisioned inserts and revocation CAS, monotonic no-upsert usage telemetry, and exact organization-lifecycle deletion. Plaintext remains one-time output only.
Privileged administration uses declared default-deny capabilities for global OIDC clients, organizations, alert rules, users, global-administrator lifecycle, and signing-key rotation, plus tenant-scoped organizations, roles, memberships, app connections, SSO, SCIM tokens, billing, and alert rules. Entry authorization requires an active persisted JWT/session/user chain and, for tenant access, exactly one current role in the target organization. Existing mutation fences recheck live actors for OIDC clients, organization suspension, global user suspension and administrative purge initiation, global-administrator lifecycle, signing-key rotation, and tenant mutations. Global-administrator grant and removal additionally require an exact reviewed user revision, caller-stable operation ID, distinct actor and target, fresh user-verified passkey, one shared last-active-administrator fence, and purpose-bound attempted plus terminal audit events. Administrative user purge, organization suspension, and signing-key rotation use the same two-minute passkey class and reassert the persisted session inside their mutation fences. Tenant invitation creation, cancellation, resend, and bulk creation plus member removal, member-role replacement, and ownership transfer use the five-minute passkey class and reassert both the same persisted session and live tenant capability inside their mutation fences.
Direct platform capability assignments are limited to the declared delegable subset and active non-administrators. Changes require an exact User revision, caller-stable operation ID, distinct actor and target, a passkey authenticated within two minutes, mutation-time reauthorization, and attempted plus terminal audit. Promotion and suspension clear direct assignments. Custom organization roles carry sorted, unique delegable tenant capabilities; malformed definitions fail closed, and organization deletion or ownership transfer cannot be delegated.
Emergency platform access is a separate break-glass lifecycle. An active
non-administrator with the direct global.break-glass.request capability can
request only global.oidc-client.manage, global.organization.manage,
global.alert.manage, or global.user.manage for 60 through 1800 seconds.
Requests use an exact User revision, caller-stable operation ID, a closed
justification code, and a passkey authenticated within two minutes. A distinct
live global administrator must approve within ten minutes. The grant records
custody-protected approver identity, expires automatically, records its first
use, emits structured audit and high/critical global alerts, and must be closed
with a durable confirmed or escalated post-use review. It never grants global
administrator management, account deletion, signing-key rotation, or approval
authority. Promotion to global administrator is blocked while a request or
grant remains open, and review immediately terminates an active grant.
Custom-role definition changes use that same tenant-privilege class. App connection and role-mapping changes, SSO connection and domain-verification changes, and SCIM bearer-token creation or revocation use the five-minute tenant-security class; each reasserts the persisted session, active organization, and live capability inside its guarded mutation. Organization settings use the five-minute tenant-privilege class. Organization deletion uses the five-minute tenant-security class, binds resumable work to the initiating owner, and reasserts a current eligible user plus fresh persisted passkey session before every deletion stage and finalization boundary.
Tenant billing changes and global or tenant alert-rule changes use separate five-minute passkey classes. Billing reasserts the same persisted session, active organization, and live billing capability inside its organization fence. Alert-rule creation, update, and deletion reload and recheck the same strong global or tenant authority inside the existing actor, recipient, and organization fences before persistence.
Confidential global OIDC client creation, client-secret rotation, and delivery acknowledgement require a passkey authenticated within five minutes. The caller supplies a canonical RSA-3072 or RSA-4096 OAEP-SHA-256 public key and stable operation ID. The server atomically persists only the secret hash plus an encrypted, actor/request-bound delivery receipt; exact retries return the same ciphertext and cannot rotate twice. The browser SDK verifies and decrypts the envelope with its caller-held non-exportable private key. Exact acknowledgement then removes the ciphertext irreversibly while retaining a compact idempotency tombstone. No confidential creation or rotation response contains plaintext.
Password and login-identifier changes, TOTP disablement, backup-code regeneration, passkey registration or revocation, and Passport device enrollment or revocation require a passkey authenticated within five minutes. The same persisted session is reasserted inside the credential or identity mutation fence. To avoid a first-factor deadlock, a password, magic-link, or federated primary session may enroll only its first passkey or TOTP factor when that primary authentication is less than five minutes old; refresh activity does not renew this window. Password recovery remains a separate proof path and does not qualify as passkey step-up. A recovery request must carry exactly the current account-bound, ten-minute, one-time reset token and a 15–128 Unicode code-point password, normalized with NFC. Under the account identity fence, the server consumes that proof, invalidates every email-action token and pending user-bound MFA/WebAuthn challenge, revokes all platform sessions, JWTs, and OIDC state, and records the revocation before writing the new password. It then sends a security notification by both email and the recovered account's enrolled Passport push channel without disclosing reset credentials. Every new password in registration, authenticated change, or self-service recovery is checked against the HIBP Pwned Passwords range API. Only the first five hexadecimal SHA-1 characters leave the service, padded range responses are requested and cached for one hour, and provider or response-integrity failure rejects the change. Passkeys, TOTP, backup codes, and Passport devices remain enrolled recovery factors.
Operational Health Endpoints
These unauthenticated endpoints are intended for load balancers, orchestrators, and Docker runtime checks. They are host-agnostic: unlike every other route, they answer GET/HEAD on the listener regardless of the request's Host header, so in-container probes against 127.0.0.1:2999 and platform replica-health probes against the container IP see them without matching any configured domain surface.
| Route | Methods | Status | Purpose |
|---|---|---|---|
/healthz |
GET, HEAD |
200 |
Process liveness once the HTTP server can respond |
/livez |
GET, HEAD |
200 |
Liveness alias for orchestrators that use live/readiness naming |
/readyz |
GET, HEAD |
200 only in the ready lifecycle state with live MongoDB and audit-provider evidence, otherwise 503 |
Readiness for routing traffic to the instance |
GET responses use Cache-Control: no-store and return JSON with ok, status, service, and version. Development IdP responses additionally report degraded: { audit: "ephemeral-memory", platform: "test-authorization" }; this explicit test-only degradation does not make readiness fail. Readiness reports starting, ready, draining, failed, or stopped; new business requests receive 503 outside ready.
The Docker image HEALTHCHECK probes http://127.0.0.1:2999/healthz so a deliberately draining instance is not mistaken for a dead process. Load balancers and orchestrators must use /readyz for traffic admission.
Passport And Mobile Approval Flow
PassportManager powers the trusted-device side of idp.global. A web session can create a passport enrollment challenge, the Swift app completes enrollment through a QR/NFC pairing payload, and later sign-in or identity checks can be approved by the paired device with signed challenge responses.
The typed request surface includes:
createPassportEnrollmentChallengeandcompletePassportEnrollmentfor pairing a trusted device.getPassportDevicesandrevokePassportDevicefor account-level device management.createPassportChallenge,approvePassportChallenge,rejectPassportChallenge, andlistPendingPassportChallengesfor approval flows.getPassportDashboard,listPassportAlerts, andmarkPassportAlertSeenfor mobile app dashboards and notifications.registerPassportPushTokenfor push delivery setup.
Passport devices, challenges, and nonce attempts use exact runtime-validated records under the live-user/account-purge fence. Enrollment and terminal challenge retries are idempotent, devices become operational only after their approved enrollment binding exists, public keys remain globally reserved after revocation while the device record is retained, and nonce replay state covers the full accepted clock-skew window. Challenge push hints use expiring delivery leases with accepted at-least-once retry after an uncertain outcome. Current account authentication eligibility is rechecked inside the fence before new or pending enrollment/challenge grants, signed-device access, or challenge push delivery; exact terminal retries may still repair their stable audit event. Direct deletion is reserved for exact nonce expiry and the account-purge cascade.
MFA And Passkeys
The reception backend supports real multi-factor authentication for account logins:
- TOTP enrollment with
startTotpEnrollmentandfinishTotpEnrollment. - Hashed one-time backup codes through
regenerateBackupCodesandverifyMfaChallenge. - WebAuthn passkey registration, revocation, passwordless login, and MFA step-up through the
startPasskey*andfinishPasskey*request pairs. - Password and magic-link logins return
twoFaNeeded,mfaChallengeToken, andavailableMfaMethodsinstead of a refresh token when MFA is configured.
Every persisted login session carries closed server-derived evidence for its
primary authentication method/time and exact MFA factor/time. Refresh and
transfer-token activity can update lastActive, but cannot advance either
authentication timestamp. The central authorization authority can require a
fresh user-verified passkey using the approved two- or five-minute operation
class. TOTP and backup codes are recovery factors and do not qualify for
global administration; no managed-device strong factor exists yet.
Authentication-method changes use the five-minute passkey class. The only exception is narrowly scoped first-factor bootstrap from a primary authentication less than five minutes old while the relevant active factors do not yet exist. Pending Passport enrollment records retain the exact authorizing session internally until device creation; serializers never expose that binding.
Global-administrator grants and removals use setGlobalAdmin. Callers first
review IGlobalUserAdminDto.revision, then submit that exact revision with a
caller-stable operationId. The server requires a distinct active global
administrator with a passkey authenticated within two minutes, serializes all
lifecycle decisions, preserves at least one active administrator, and emits
durable attempted plus terminal audit outcomes. Global administrators must
have their authority removed by another administrator before deleting their
own account. Administrative account purge, organization suspension, and OIDC
signing-key rotation use the same two-minute passkey class. Rotation first
persists a caller-stable request bound to the reviewed active key and expires it
after ten minutes without changing signing material. A different active global
administrator must approve with a separately fresh passkey session. The server
locks and revalidates both administrators, then atomically rotates the key and
closes an exact custody-tokenized retry receipt in the keyring CAS. Request
and terminal outcomes are purpose-bound in the protected audit trail.
A global administrator who has lost all passkeys may request one controlled replacement-passkey enrollment from a fresh TOTP or backup-code session. The request is exact-revision and caller-stable, expires after ten minutes, and must be approved by a distinct active global administrator using a passkey authenticated within two minutes. Approval opens a 15-minute grant bound to the requesting session. The first replacement passkey closes the grant atomically; retry reconciliation cannot enroll a second passkey. Request, activation, completion, expiry conflicts, demotion, and suspension share the administrator lifecycle fence and emit structured audit plus global security alerts.
TOTP secrets are AES-GCM encrypted. IDP_TOTP_ENCRYPTION_KEY is required and must stay stable across deployments so enrolled credentials remain decryptable.
Domain Surfaces
https://idp.global(IDP_BASEURL) is public and remains the permanent issuer, discovery, OIDC, SAML, and SCIM origin.https://login.idp.global(IDP_LOGIN_BASEURL) is public and hosts login, registration, MFA, consent, recovery, and invitation flows.https://app.idp.global(IDP_APP_BASEURL) is public and hosts each user's authenticated customer dashboard and tenant-scoped application API.https://superadmin.idp.global(IDP_SUPERADMIN_BASEURL) is a privateSTANDARDroute for global administrators and privileged administrative CLI calls. It must not be declared as a public deployment route.
The issuer UI is sourced from @idp.global/landingpage, but it is not a separate runtime service. This app remains the sole owner of https://idp.global, embeds the package in its browser bundle, and copies only the package's two manifest-qualified console images into the build after verifying their names, dimensions, opacity, and SHA-256 hashes.
Incoming requests are dispatched to a surface by their Host header against these four configured origins; requests for any other host are refused with 404, except the host-agnostic operational health endpoints described in the Operational Health Endpoints section above. In production the four variables are required and must use four distinct hostnames (self-hosters substitute their own domains); outside production the dedicated browser surfaces default to IDP_BASEURL.
Public reachability of the app surface exposes the authentication boundary, not customer or administrative data. Session authentication, organization membership, tenant isolation, roles, capabilities, and step-up checks continue to authorize every protected operation.
What each surface exposes beyond static assets and its own UI paths:
- The login surface answers
POST /typedrequestfor an allowlist of public sign-in methods only, and refuses every WebSocket upgrade. The method allowlist is enforced by the HTTP route, so a socket on that origin would expose the whole typed router; for the same reason the login surface does not register the application service worker (it still serves the worker script so a previously installed worker can update and be retired). - The app surface answers non-privileged
POST /typedrequestmethods and admits same-origin WebSocket upgrades on both the reception path and the origin root — the application client upgrades on/typedrequest, while the service worker upgrades on/. Global-admin methods are refused both by HTTP admission and by recursive server middleware on every public WebSocket handler router. A one-time transfer arriving on this surface is fully settled through the application state's owned client before service-worker registration, preventing a first-run cache reload from racing the single-use credential. - The superadmin surface answers
POST /typedrequestover HTTP, refuses every WebSocket upgrade, never registers the application service worker, and renders only global user, organization, and OIDC-client administration. Existing JWT, global-capability, and fresh-MFA checks remain authoritative inside every privileged handler. Network privacy is supplied by the route'sSTANDARDsource profile; the hostname must remain unreachable through public ingress, including with a spoofedHostheader. - The issuer surface answers protocol routes only, never browser RPC, and never registers a service worker.
Both first-party consoles are authorized as session transfer targets by IDP_APP_BASEURL and IDP_SUPERADMIN_BASEURL: the login surface hands a signed-in session to either console through the same transfer-token exchange third-party relying parties use. Their authority comes from runtime configuration rather than registered App documents, and distinct internal references preserve the exact target through SAML handoffs. No bootstrap seeding or operator registration is needed.
SDK Example
The authenticated application shell uses the dedicated SDK browser entrypoint published by @idp.global/sdk.
Relying parties should integrate through dynamic OIDC discovery at https://idp.global/.well-known/openid-configuration, not the first-party TypedRequest API.
import { IdpClient } from '@idp.global/sdk/browser';
const idpClient = new IdpClient(
'https://app.idp.global',
{ appUrl: 'https://app.idp.global/' },
{ loginBaseUrl: 'https://login.idp.global' },
);
await idpClient.enableTypedSocket();
const isLoggedIn = await idpClient.determineLoginStatus();
if (!isLoggedIn) {
const loginResult = await idpClient.requests.loginWithUserNameAndPassword.fire({
username: 'user@example.com',
password: 'correct horse battery staple',
});
if (loginResult.refreshToken) {
await idpClient.refreshJwt(loginResult.refreshToken);
}
}
const whoIs = await idpClient.whoIs();
console.log(whoIs.user.data.email);
CLI Example
The terminal client lives in ts_idpcli/ and is published as @idp.global/cli.
idp login
idp whoami
idp orgs
idp members --org <org-id>
idp invite --org <org-id> --email user@example.com
The CLI uses public https://app.idp.global WebSocket RPC for login and customer workflows, and private https://superadmin.idp.global/typedrequest HTTP RPC for admin-* commands. IDP_URL overrides the customer endpoint; IDP_SUPERADMIN_URL independently overrides the private endpoint. When only IDP_URL is set, both collapse to that value for local/self-hosted development. Protected operations require authenticated credentials, secrets stay in the OS keyring, and only non-secret metadata is written to ~/.idp-global/credentials.json.
Shared Interfaces
The sibling @idp.global/interfaces package exports the type contracts shared across the stack:
data/*for users, orgs, roles, JWTs, sessions, devices, billing plans, apps, passport records, alerts, OIDC, SAML, and SCIM payloads.request/*for auth, registration, user, org, invitation, app, admin, billing, JWT, passport, alert, OIDC, SAML, and SCIM request contracts.tags/*for shared tag exports.
Frontend
ts_web/ is the web application bundle. It contains:
- Login and registration prompts.
- A registration stepper.
- Account navigation and account views.
- Organization creation and bulk invite modals.
- Billing and Paddle setup views.
- Organization SAML/SCIM configuration with DNS verification state.
- A global admin view.
Package Scripts
| Command | Purpose |
|---|---|
pnpm build |
Build TypeScript output and frontend bundle |
pnpm watch |
Run backend watch mode and frontend bundle watch |
pnpm test |
Build and run the test suite |
pnpm run preflight:data |
Verify the exact database/schema and identity invariants; this is one subordinate check and never release authorization |
pnpm run preflight:namespace -- --expect=blank|prebootstrap|stable |
Classify a namespace with read-only inspection, verify the expected state, and fail on read drift without installing or repairing anything |
pnpm run build:docker |
Build one clean, configured multi-platform candidate into the project-local tSDocker registry |
pnpm run digest:docker |
Capture and validate the candidate's canonical tSDocker digest JSON and source receipt |
pnpm run test:docker |
Test that exact persisted candidate by expected digest without rebuilding |
pnpm run verify:docker |
Bind native runtime, image-config, platform-manifest, and embedded supply-chain evidence to the exact candidate digest |
pnpm run seal:docker-evidence |
Revalidate and print the deterministic technical evidence seal; it explicitly does not authorize release |
pnpm run supplychain:evidence |
Generate deterministic CycloneDX, dependency-license, root-license, and missing-license evidence for the current platform |
Current-Schema and Data-Preflight API
The backend entrypoint exports CurrentSchemaManager, currentSchemaManifest, currentSchemaManifestDigest, currentSchemaVersion, the identity-preflight analyzers, the count-only release-data preflight functions, and the namespace-preflight API: namespacePreflightExpectations, runNamespacePreflight, and evaluateNamespacePreflight. Embedding and operator tooling can use these APIs to install or verify the one accepted blank/current namespace and to detect schema, identity, or held-fence blockers without logging identifiers. Namespace preflight uses read-only collection, count, schema-state, index, and data-conformance inspection. It maps expectations blank, prebootstrap, and stable to classifications blank, current-prebootstrap, and current-stable; other classifications are nonblank-unmanaged and managed-incompatible. It records before/after counts and fails if the namespace changes during observation.
Current-data verification checks the complete raw shape of all revisioned documents, Apps, the five user-bound OIDC authorization/token/consent collections, two MFA credential collections, three Passport collections, the identity-free OIDC transaction and SAML request collections, and the singleton startup controls. OIDC and Passport inserts are acknowledged and runtime-validated. Passport inserts, user-created global App writes, AppConnection creation, and OIDC consent grants are serialized against the live-user/purge fence. Apps use exact per-type validation and revision CAS; AppConnection inserts reconcile committed acknowledgement loss without inherited upserts. Consent grants and Passport lifecycle transitions use exact no-upsert CAS, while Passport telemetry uses named monotonic mutations.
These checks establish only the database contract. They do not authorize a package, tag, container, deployment, or production route opening; every gate in readme.plan.md still applies.
Docker Candidate Diagnostics
These commands are non-publishing diagnostics, not a qualified release path. They require one fresh project-scoped session ID and one clean source checkout. The wrapper rejects tracked/untracked changes and verifies that every repository-ignored path is excluded from the Docker context. Keep the same ID and checkout for the lifecycle; a new build attempt requires a new ID.
export TSDOCKER_SESSION_ID="idp-app-<source-and-run-specific-id>"
pnpm run build:docker
pnpm run digest:docker
# Run the following two commands natively on linux/amd64 and linux/arm64.
pnpm run test:docker
pnpm run verify:docker
# Run only after both native platform records are present.
pnpm run seal:docker-evidence
The canonical registry workspace remains below
.nogit/docker-registry/$TSDOCKER_SESSION_ID/. The raw tSDocker digest JSON and the
source/tool/test receipt remain below .nogit/release-evidence/. The receipt binds the
candidate to the Git revision, package version, Dockerfile pattern, project-local tSDocker
version, configured platform set, clean tag, and top-level digest. Digest capture retains
the exact raw OCI index plus runnable and attestation manifests, recomputes their digests
and sizes, binds each config and layer descriptor, and re-reads the project-local registry
when evidence is consumed. Native verification records each host platform independently,
binds the local image ID to that platform's config digest, verifies the in-image evidence
artifact hashes, and reaches evidence-sealed only after both linux/amd64 and
linux/arm64 name the same candidate digest. The terminal receipt and verifier output both
carry releaseAuthorized: false. The generated evidence includes a normalized
CycloneDX SBOM, installed production-license inventory, the root license.md hash, and a
fail-closed missing-license gate.
The final successful verify:docker creates or reuses a deterministic technical evidence
seal. A recoverable retry produces identical seal content; a stale receipt lock remains a
fail-closed operator condition. seal:docker-evidence only revalidates and prints that
existing technical seal with releaseAuthorized: false. It is not release acceptance and does not
prove provenance, signatures, vulnerability-policy compliance, reproducibility, qualified
notices, immutable remote publication, or deployment safety. Those gates remain mandatory
in readme.plan.md.
The GitZone Docker release target is intentionally disabled. GitZone CLI 2.23 invokes a
global tsdocker binary and cannot transport tSDocker 3 expected-digest evidence, so it
must not own image publication. There is deliberately no release:docker script.
@git.zone/tsdeploy owns production publication: it reserves a fenced Cloudly operation,
builds and tests with the project-local tSDocker 3.2.0, pushes the exact version tag through
an operation-scoped registry credential, requires source/configuration/index-bound
provenance, SBOM, SSH signature, vulnerability-policy, and explicit release-authorization
evidence, then promotes only Cloudly's independently observed immutable registry release.
The Gitea branch workflow runs the source build and regression suite only. It deliberately does not construct a container candidate or release evidence before Gate 0 reserves an unused version and candidate identity. The stable-tag workflow hard-fails instead of rebuilding: it must eventually verify retained accepted digest/evidence without constructing a new candidate.
Self-Hosting
The app ships as a single Docker image and needs a MongoDB instance next to it. Runtime configuration and database state are fail-closed. Partial, unknown, or malformed bootstrap environment configuration is rejected before the HTTP listener starts. With no bootstrap variables at all, a blank production database reaches the database/bootstrap-state gate after listener startup: /healthz and /livez remain 200, /readyz reports 503 failed, and every business/OIDC route returns 503 with Retry-After: 1 and service_unavailable until the operator stops and restarts the instance with complete bootstrap input.
The packaged executable composes its production audit runtime from environment configuration.
OpenBao Transit protects audit identities, Lossless S3-compatible object storage provides the
compliance-mode retention sink, and serve.zone service mail provides durable dead-letter
alerting. Startup and /readyz require deadline-bounded, challenge-bound evidence for the
exact configured keys, active retention lock and sentinel object, and alert route.
First Production Launch
A fresh production database never creates an administrator implicitly. After the one current-schema installer establishes and verifies the exact empty namespace, the service requires one explicit initial-admin operation. The operation creates exactly one global administrator, one organization, one owner role with manual provenance, canonical email/username ownership records, and one organization-created structured audit event. It creates no demo users, OAuth apps, API tokens, or other defaults.
Set all of these values for the first launch only:
| Variable | Constraint |
|---|---|
IDP_INITIAL_BOOTSTRAP_MODE |
Exactly initial-admin. This is the explicit opt-in. |
IDP_INITIAL_BOOTSTRAP_OPERATION_ID |
Stable operator-chosen id, 1–128 ASCII characters. The first character must be alphanumeric; remaining characters may also use ., _, :, or -. Reuse it after an interrupted attempt. |
IDP_INITIAL_BOOTSTRAP_ADMIN_NAME |
Display name for the initial administrator; 1–200 characters with no control characters. |
IDP_INITIAL_BOOTSTRAP_ADMIN_EMAIL |
Valid administrator email, at most 320 characters; stored in canonical lowercase form. |
IDP_INITIAL_BOOTSTRAP_ADMIN_USERNAME |
Initial username, 1–320 characters with no control characters; stored in canonical lowercase form. |
IDP_INITIAL_BOOTSTRAP_ORGANIZATION_NAME |
Display name for the initial organization; 1–200 characters with no control characters. |
IDP_INITIAL_BOOTSTRAP_ORGANIZATION_SLUG |
Lowercase slug, 3–64 characters, using alphanumerics and single hyphen-separated segments. |
IDP_INITIAL_BOOTSTRAP_PASSWORD_FILE |
Absolute path to the mounted password file described below. The password itself must never be placed in an environment variable or command argument. |
All eight variables are one contract. Companions without the mode, an unknown mode, a missing companion, or malformed metadata fail configuration loading before the HTTP listener starts.
The password path must resolve directly to a regular file; symlinks are rejected. The file must be readable by runtime UID 10001, must not be group- or world-writable, and must contain 15–512 bytes of valid UTF-8 with no control character or trailing newline. After NFC normalization, the password must contain 15–128 Unicode code points. The reader requires operating-system no-follow support and verifies that device, inode, ownership, mode, size, and timestamps do not change while it is read. Docker secrets mounted as regular read-only files are suitable. Kubernetes projected-secret paths are symlinks by default, so expose the selected key as a regular subPath mount and pass that path instead.
Bootstrap accepts only the exact completed current-schema manifest and empty application state. Any user, organization, role, identity authority, audit entry, foreign collection or index, conflicting request, or wrong password blocks without overwriting or deleting that state. Identical concurrent calls converge on the same deterministic graph. An interrupted call must be restarted with the exact same metadata and password; only the bootstrap installer may take over its own expired lease because every effect is deterministic and forward-only.
When /readyz becomes 200, verify administrator login, stop the instance, remove every IDP_INITIAL_BOOTSTRAP_* value and the password mount, and restart. The terminal receipt is retained without its transient password verifier, normal identity data may evolve, and later startup does not need or read the bootstrap password. Keeping matching metadata configured is tolerated after completion, but removal is the required operator cleanup.
Environment Variables
| Variable | Required | Purpose |
|---|---|---|
IDP_ENV |
yes | Runtime mode: production, development, test, or local. Anything unset defaults to production (fail-closed). |
INSTANCE_NAME |
yes | Instance identifier used in logs and metrics. |
MONGODB_URL |
yes | MongoDB connection string. |
IDP_BASEURL |
yes | Issuer origin (must be https:// in production; http:// only for localhost in non-production). Credential-free origin URL: no path, query, fragment, or userinfo. |
IDP_LOGIN_BASEURL |
production | Login-surface origin. Optional outside production (defaults to IDP_BASEURL); same URL constraints as IDP_BASEURL. |
IDP_APP_BASEURL |
production | Public customer-console origin. Optional outside production (defaults to IDP_BASEURL); same URL constraints as IDP_BASEURL. |
IDP_SUPERADMIN_BASEURL |
production | Private global-administration origin. Optional outside production (defaults to IDP_BASEURL). In production all four surface origins must use distinct hostnames; startup fails otherwise. |
SERVEZONE_PLATFORM_AUTHORIZATION |
yes | serve.zone platform binding for outbound email. test is rejected in production. |
IDP_BACKEND_TOKEN |
production | Shared secret (≥32 chars) that backend consumers present for JWT public-key and blocklist retrieval. |
IDP_TOTP_ENCRYPTION_KEY |
yes | Key material (≥32 chars) encrypting TOTP secrets at rest. Never rotate casually — enrolled authenticators become unreadable. |
IDP_METRICS_TOKEN |
no | Bearer token (≥32 chars) gating GET /metrics (Prometheus text format). Unset disables the endpoint (404). |
IDP_SHUTDOWN_GRACE_PERIOD_MS |
no | Grace period for draining admitted requests and background work before reporting a shutdown timeout (integer from 1000 through 900000; default 30000). Cleanup continues after a timeout report. |
IDP_INITIAL_BOOTSTRAP_* |
first production launch only | Complete one-shot administrator/organization configuration from the preceding section. Partial configuration is rejected. Remove all values and the mounted password file after the verified bootstrap restart. |
docker-compose Example
services:
idp:
image: code.foss.global/idp.global/app@sha256:<recorded-release-digest>
restart: unless-stopped
ports:
- '2999:2999'
read_only: true
tmpfs:
- /tmp:size=64m,mode=1777
stop_grace_period: 45s
environment:
IDP_ENV: production
INSTANCE_NAME: idp-selfhosted
MONGODB_URL: mongodb://idp:change-me@mongodb:27017/idp?authSource=admin
IDP_BASEURL: https://idp.example.com
IDP_LOGIN_BASEURL: https://login.idp.example.com
IDP_APP_BASEURL: https://app.idp.example.com
IDP_SUPERADMIN_BASEURL: https://superadmin.idp.example.com
SERVEZONE_PLATFORM_AUTHORIZATION: '<your serve.zone binding>'
IDP_BACKEND_TOKEN: '<random 32+ char secret>'
IDP_TOTP_ENCRYPTION_KEY: '<random 32+ char secret, back it up>'
IDP_SHUTDOWN_GRACE_PERIOD_MS: 30000
IDP_INITIAL_BOOTSTRAP_MODE: initial-admin
IDP_INITIAL_BOOTSTRAP_OPERATION_ID: first-production-launch
IDP_INITIAL_BOOTSTRAP_ADMIN_NAME: '<initial administrator name>'
IDP_INITIAL_BOOTSTRAP_ADMIN_EMAIL: '<initial administrator email>'
IDP_INITIAL_BOOTSTRAP_ADMIN_USERNAME: '<initial administrator username>'
IDP_INITIAL_BOOTSTRAP_ORGANIZATION_NAME: '<initial organization name>'
IDP_INITIAL_BOOTSTRAP_ORGANIZATION_SLUG: '<initial-organization-slug>'
IDP_INITIAL_BOOTSTRAP_PASSWORD_FILE: /run/secrets/idp-bootstrap-password
secrets:
- idp-bootstrap-password
depends_on:
- mongodb
mongodb:
image: mongo:8
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: idp
MONGO_INITDB_ROOT_PASSWORD: change-me
volumes:
- mongodb-data:/data/db
volumes:
mongodb-data:
secrets:
idp-bootstrap-password:
file: ./secrets/idp-bootstrap-password
Create the password file without a trailing newline and protect the host copy before starting Compose. After the successful bootstrap verification, remove the eight bootstrap environment entries and the service secret mount, then restart the service. Use only a released immutable digest; the placeholder above must be replaced before deployment.
Health endpoints for orchestration: GET /healthz (liveness), GET /readyz (readiness; reports the running version and lifecycle state). The image ships a Docker HEALTHCHECK probing /healthz; configure traffic admission against /readyz.
Rollback by Digest
Record the immutable multi-architecture digest and workload tag for every release. Roll back by selecting that recorded immutable artifact in the orchestrator; never move or retag latest.
Cloudly deployments must follow the release and rollback runbook. The first production launch has no legacy-data upgrade or cutover. Before public traffic is enabled, rollback means keeping routing closed, returning to the recorded immutable artifact, and either retaining the untouched empty target or restoring the fresh post-bootstrap backup proven by the isolated restore rehearsal. After real production data exists, every later release must declare its own data-compatibility and backup requirements; an image rollback must never be assumed to reverse schema or data changes.
Observability
- Production logs are JSON lines on stdout (one object per log event, including commitinfo context). Non-production modes log human-readable text.
- Every handled typed request logs method, request id (correlation id), duration and error class. Payloads are never logged.
- Raw HTTP endpoints honor an incoming
x-request-idheader and echo it on the response. GET /metrics(withAuthorization: Bearer $IDP_METRICS_TOKEN) exposes process and system metrics in Prometheus text format.
Operational runbooks (health monitoring, audit export, access reviews, release/rollback) live in docs/soc2/.
Repository Notes
- Package manager:
pnpm - Main backend entrypoint:
ts/index.ts - Frontend entrypoint:
ts_web/index.ts - Browser SDK entrypoint:
@idp.global/sdk/browser - User CLI entrypoint:
ts_idpcli/index.ts(published as@idp.global/cli) - Packaged server/administrator CLI entrypoint:
cli.js, including the app-owneddevidp-runtimemachine protocol
License and Legal Information
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the license.md file.
Please note: The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
Trademarks
This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.
Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
Company Information
Task Venture Capital GmbH
Registered at District Court Bremen HRB 35230 HB, Germany
For any legal inquiries or further information, please contact us via email at hello@task.vc.
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.