# @idp.global/interfaces

Shared TypeScript interfaces and TypedRequest contracts for the idp.global ecosystem.

This package contains public data shapes, DTOs, typed RPC request definitions, and shared tags used by the idp.global backend, browser client, CLI, web UI, and external integrations. Its dedicated Node.js `devidp` subpath also provides the exact local Development IdP contract validators, canonical fingerprinting, and deterministic namespace-owned identifier derivations.

## Issue Reporting and Security

For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://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/](https://code.foss.global/) account to submit Pull Requests directly.

## Install

```bash
pnpm add @idp.global/interfaces
```

## Public API

```ts
import { data, dto, request, tags } from '@idp.global/interfaces';
import * as devidp from '@idp.global/interfaces/devidp';
```

The root export exposes four namespaces:

```ts
export {
  data,
  dto,
  request,
  tags,
};
```

The dedicated Node.js `devidp` subpath exports the strict local Development IdP
manifest/result contract, canonical fingerprinting, and deterministic
namespace-owned identifiers. It does not provision users, grant roles, start
containers, or contain credentials:

```ts
const manifest = devidp.normalizeDevIdpManifest(rawManifest);
const fingerprint = devidp.fingerprintDevIdpManifest(manifest);
const result = devidp.assertDevIdpResultMatchesManifest(rawResult, manifest);
```

Development IdP manifest schema v3 binds the fixed
`platform-personas-v1` authority profile. Authority is derived from the persona
name and cannot be supplied or widened by a manifest caller:

- `testuser` is an ordinary non-administrator with no global capabilities.
- `testmoderator` has exactly `global.alert.manage`, `global.alert.read`,
  `global.user.manage`, and `global.user.read`; normal strong-MFA requirements
  still apply to protected mutations.
- `testsuperadmin` is a global administrator with no direct capability
  assignments; administrator authority is derived by the IdP.

Schema v3 also requires `rpClient.tlsHostnames` to arrive
as an already sorted, unique inventory. Every entry must be exact `localhost`
or a concrete lowercase `.localhost` hostname, and the inventory must cover the
hostname of `appUrl` plus every redirect and post-logout URI. Additional
declared local surfaces such as `superadmin.localhost` are allowed. The result
contract remains schema v1 because its manifest fingerprint already binds the
complete schema-v3 input.

## Data Contracts

Use `data` for durable and transportable idp.global object shapes.

Common data contracts include users, JWTs, login sessions, registration sessions, organizations, roles, invitations, billing plans, apps, app connections, finite activity classifications, alerts, alert rules, abuse windows, passport devices, passport challenges, passport nonces, and OIDC payloads.

```ts
import { data } from '@idp.global/interfaces';

const organization: data.IOrganization = {
  id: 'org_1',
  data: {
    name: 'Acme',
    slug: 'acme',
    status: 'active',
    billingPlanId: 'plan_free',
    roleIds: [],
  },
};
```

Persisted `data.IJwt` and `data.ILoginSession` shapes never contain plaintext
refresh or transfer tokens. Session persistence exposes only refresh-token
hashes, refresh-token rotation history, and the atomic transfer-grant tuple
`transferTokenHash`, `transferTokenExpiresAt`, and `transferTargetHash`.
Every login session also requires closed server-derived primary and MFA
authentication evidence; refresh operations must not advance those timestamps.
The admin contract includes `setGlobalAdmin` for controlled platform
administrator grant/removal. Implementations must require fresh strong MFA,
distinct actor and target identities, serialized compare-and-set mutation, and
must never remove the last active global administrator. The request requires a
caller-stable `operationId` and the exact reviewed `expectedUserRevision` so
retries reconcile one durable attempt without overwriting a newer decision.
`IGlobalUserAdminDto.revision` supplies that exact review token in directory
and mutation responses.
Grant/removal attempt and result events use the closed `global_admin_granted`
and `global_admin_removed` activity actions.

The authorization data contract exports the complete global and tenant
capability sets plus the narrower delegable subsets. Direct platform
assignments use `setGlobalCapabilityAssignments`, an exact User revision, and
a caller-stable operation id. Customer-defined organization roles carry a
sorted `capabilities` list; tenant deletion and ownership transfer remain
reserved to the built-in owner role.

The target hash is derived server-side from the canonical, authorized
`ITransferTarget.appUrl`; the raw target URL is never persisted in session
data. Opaque tokens and the transfer target remain limited to the request and
response contracts that transport them.

## TypedRequest Contracts

Use `request` when registering handlers or creating typed clients with `@api.global/typedrequest` or `@api.global/typedsocket`.

```ts
import { request } from '@idp.global/interfaces';

type LoginRequest = request.IReq_LoginWithEmailOrUsernameAndPassword;

const payload: LoginRequest['request'] = {
  username: 'user@example.com',
  password: 'secret',
};
```

JWT verification-key distribution is keyset-only and uses plural method names:

```ts
type GetValidationKeys = request.IReq_GetPublicKeysForValidation;
type PushValidationKeys = request.IReq_PushPublicKeysForValidation;

const transferRequest: request.IReq_ExchangeRefreshTokenAndTransferToken['request'] = {
  refreshToken: 'opaque-refresh-token',
  transferTarget: {
    appUrl: 'https://app.example/',
  },
};
```

Backend TypedSocket clients authenticate the exact request peer with
`IReq_RegisterBackendServiceConnection`. The request carries only the backend
token and success is exactly `{ registered: true }`. The idp.global handler
validates the token before resolving that peer and assigning the protected
backend-service role as server-owned connection state; clients do not set the
role tag themselves. The tag payload is exactly empty, so the backend token is
used only for validation and is never retained in connection tag state.

`transferTarget` is required both when a refresh token issues a transfer token
and when a transfer token is consumed. The server authorizes and canonicalizes
the target before binding its server-derived hash to the outstanding transfer
token.

Request groups cover login, registration, JWT refresh, user/session queries, organization membership, invitations, apps, billing, admin actions, alerts, passport device flows, password reset, device IDs, and OIDC authorization.

The OIDC V2 authorization contracts
`IReq_InspectOidcAuthorizationV2`, `IReq_PrepareOidcAuthorizationV2`,
`IReq_CompleteOidcAuthorizationV2`, and `IReq_DenyOidcAuthorizationV2` model an
opaque browser handoff. Only a one-time `transactionId` crosses the browser
boundary; the original OAuth request remains server-side.

Registration may retain that opaque transaction in its server-side session.
`IReq_FirstRegistration` accepts it optionally, while successful email-token
or email-code proof and registration completion return the authoritative stored
value. Implementations should keep it out of registration email links and use
the existing authenticated OIDC prepare/complete requests for final binding.

OIDC app contracts expose only client configuration and safe credential
metadata. Client-secret hashes, signing private keys, and persistence records
for authorization codes, access tokens, refresh tokens, and token families
remain backend-internal; protocol request and response values remain public.

## DTO Contracts

Use `dto` for normalized transfer objects grouped by activity, alerts, apps, billing, invitations, MFA, organizations, passport, and users. `dto.TActivityEventDto` is a discriminated structured event: it exposes only a finite action, timestamp, outcome, optional reason code, fixed target type, and allowlisted action-specific facts. It never carries event, actor, or target identifiers; free text; network data; integrity material; or delivery state. Public OIDC support includes `data.IOidcSettings` and redacted `data.IJwtVerificationKey` records.

```ts
const activity: dto.TActivityEventDto = {
  action: 'login',
  timestamp: Date.now(),
  outcome: 'succeeded',
  targetType: 'account',
  facts: {
    authenticationMethod: 'password',
  },
};
```

## Scope

This package is intentionally contract-only. It does not open sockets, store auth state, talk to MongoDB, send email, or implement authentication logic.

## Development

```bash
pnpm install
pnpm run build
pnpm test
```

## 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](./license) 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.
