GitHub

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

  1. Research the platform's token format: issuer, default audience, identifying claims, stable IDs, and platform-specific quirks.
  2. Create registry/oidc/providers/<name>.source.ts. Copy google.source.ts for a simple provider, or github.source.ts if you need selects or conditional fields.
  3. Generate and typecheck:
Terminal
pnpm generate <name>
pnpm typecheck
  1. Add round-trip and rejection tests to tests/providers.test.ts, then run pnpm test.
  2. Add the provider icon to the ICONS record in components/builder/data.ts.
  3. Add a page under content/docs/providers/<name>.mdx and list it in content/docs/providers/meta.json.
  4. Build the registry with pnpm registry:build.
  5. Run pnpm dev and 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

  1. Add the field to spec.fields and to a layout row. Use one field per row.
  2. Update compile to emit the claim and parse to recover the value. parse must reject claim shapes the field cannot represent.
  3. If needed, add the field to the source-only Fields type.
  4. If the field maps to a first-class claim, add that name to FIRST_CLASS_CLAIMS so additional-claim rows cannot shadow it.
  5. Regenerate, typecheck, and update round-trip tests.
  6. Update the provider's docs page so the field table and example policy stay accurate.
Terminal
pnpm generate <name>
pnpm typecheck
pnpm test

FieldSpec

PropertyMeaning
nameThe key in Fields. Map it to a claim in compile and parse.
kindOmit for text input. Use "select" with options and optional resets, or "claimsList" for additional claims.
label / labelExprA static label or a $F.field expression evaluated for each flavor.
claim / claims / claimExprThe claim name(s) shown as a mono chip. Display only — compile / parse stay the source of truth.
placeholder / placeholderExprA static placeholder or a $F.field expression.
helpHelp text shown below the field.
requiredThe empty-field error message. Required fields are validated in every flavor.
rules{ pattern, message } checks. Optional fields may still be empty.
defaultValue, trim, mono, visibleWhenField 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.