Contributing
Add a provider or field to the OIDC UI registry.
Provider components are generated. Write each provider once in registry/oidc/providers/<name>.source.ts. Running pnpm generate creates nine versions of that provider, one for each form and validation library combination.
Do not edit registry/oidc/components/provider-*.tsx or anything in registry/oidc/flavors/ — those are generated, your changes will be overwritten, and pnpm check:generated will fail. registry/oidc/components/policy-form.tsx and claims.tsx are hand-authored.
See the provider field reference for what each shipped form already collects.
Add a provider
- Research the platform's token format: issuer, default audience, identifying claims, stable IDs, and platform-specific quirks.
- Create
registry/oidc/providers/<name>.source.ts. Copygoogle.source.tsfor a simple provider, orgithub.source.tsif you need selects or conditional fields. - Generate and typecheck:
pnpm generate <name>
pnpm typecheck- Add round-trip and rejection tests to
tests/providers.test.ts, then runpnpm test. - Add the provider icon to the
ICONSrecord incomponents/builder/data.ts. - Add a page under
content/docs/providers/<name>.mdxand list it incontent/docs/providers/meta.json. - Build the registry with
pnpm registry:build. - Run
pnpm devand confirm the form renders in Preview, generated files appear in Code, and the install command resolves.
Policy logic
compile turns form values into an OIDC policy. It must only produce valid policies:
- Derive fixed issuers and audiences instead of accepting them as free text
- Add required prefixes to refs
- Wrap UUIDs where the platform requires it
parse turns a policy back into form values. Return null whenever the form cannot fully represent the policy, including policies for other providers. Each provider needs a recognizable signature so parsers do not overlap.
Keep the logic:start / logic:end region framework-independent: no React.
Add a field
- Add the field to
spec.fieldsand to alayoutrow. Use one field per row. - Update
compileto emit the claim andparseto recover the value.parsemust reject claim shapes the field cannot represent. - If needed, add the field to the source-only
Fieldstype. - If the field maps to a first-class claim, add that name to
FIRST_CLASS_CLAIMSso additional-claim rows cannot shadow it. - Regenerate, typecheck, and update round-trip tests.
- Update the provider's docs page so the field table and example policy stay accurate.
pnpm generate <name>
pnpm typecheck
pnpm testFieldSpec
| Property | Meaning |
|---|---|
name | The key in Fields. Map it to a claim in compile and parse. |
kind | Omit for text input. Use "select" with options and optional resets, or "claimsList" for additional claims. |
label / labelExpr | A static label or a $F.field expression evaluated for each flavor. |
claim / claims / claimExpr | The claim name(s) shown as a mono chip. Display only — compile / parse stay the source of truth. |
placeholder / placeholderExpr | A static placeholder or a $F.field expression. |
help | Help text shown below the field. |
required | The empty-field error message. Required fields are validated in every flavor. |
rules | { pattern, message } checks. Optional fields may still be empty. |
defaultValue, trim, mono, visibleWhen | Field behavior. visibleWhen is a $F expression. |
The generator rewrites $F.field to the correct accessor for each flavor: fields., watched., or values..
See CONTRIBUTING.md for flavor generator notes.