Silicon IAMDocs
IAM 5.2.1 is liveThe Rust SDK and CLI are published. Dependent application updates are still being verified. Coordinate each integration before enabling its new protocol. Read the migration guide →

Silicon IAM frontend

The frontend provides Carbon and Silicon signup, multiple configured accounts, application login with one organization, separate OBO consent, batch login and application bundles. See the batch login guide and bundle guide.

The SolidJS frontend has two entry points in one codebase:

The app talks only to its same-origin session gateway. This is not a static-only website: deploy the gateway with the assets. Source lives in frontend/ in the IAM repository; run the commands below there. Run the v1 backend with its complete production migrations, testing overlay, and runtime grants. See organization consent.

Local development

Requires Node 24 and npm. Install with npm ci; run npm run dev (port 4310). Configure .env.development.local first:

API_UPSTREAM=http://127.0.0.1:4320
CONSOLE_ORIGIN=http://127.0.0.1:4310
AUTH_ORIGIN=http://127.0.0.1:4310
DISPLAY_ENVIRONMENT=Local testing

Use an isolated local IAM API, its official migrations, and runtime database roles. Do not point manual test runs at production. Local development without a configured cookie key generates an ephemeral key: restarting the dev server signs out existing browser sessions. A fixed, random development-only key avoids that; never reuse a QA key in production.

The local API may expose local_otp only with explicit local-provider settings. The UI renders these codes only on a loopback hostname. Ordinary local-provider OTPs are random; 000000 is reserved for key-selected IAM testing environments.

npm run check
npm run build
# After providing server env vars, serve the actual built app + gateway:
npm start

Hosting

Nothing is published automatically. Build outputs:

Copy .env.example to an ignored environment file, supply a fresh 32-byte base64url SESSION_COOKIE_KEY, and use your hosting platform’s secret manager. Keep the same key across replicas and restarts. Changing it invalidates frontend sessions. Node can load an environment file with node --env-file=.env dist/server/node.js. Never bundle environment files into public assets.

For the intended two domains:

API_UPSTREAM=https://backend.iam.teamofsilicons.com
CONSOLE_ORIGIN=https://iam.teamofsilicons.com
AUTH_ORIGIN=https://auth.iam.teamofsilicons.com
COOKIE_DOMAIN=iam.teamofsilicons.com

Terminate HTTPS at a trusted reverse proxy, preserve the exact configured Host, proxy all paths to this server, and exclude request bodies, cookies, authorization headers, SLTs, callback URLs, and setup URLs from access/analytics logs. Do not put any untrusted app under the shared cookie domain. Both frontend origins use the same deployment configuration and encryption key.

Vercel deployment

The silicon-iam-frontend project uses the existing Vercel domain setup. Set the production variables above plus DISPLAY_ENVIRONMENT=Production; create SESSION_COOKIE_KEY as a Sensitive environment variable. Never pull the production key into a development environment or pass it as a build argument.

npm ci
npm run build:vercel
vercel deploy --prebuilt --prod --skip-domain
# After checking the deployment, promote it to the configured custom domains:
vercel promote <deployment-url>

Use the same deployment for iam.teamofsilicons.com and auth.iam.teamofsilicons.com. Keep Vercel deployment URLs protected; the gateway intentionally rejects hosts other than these two configured domains. A static-only Vite deployment will not work. The packaging step copies only the built assets and gateway, not .env files. No GitHub repository is created or pushed by these commands. Vercel's build/runtime documentation: Node.js runtime, Build Output API.

Organization invitations can link to /join?org_id=your-org on either hostname. Sign-in preserves this allowlisted internal destination and prefills the organization handle; no arbitrary return URL is accepted.

WorkOS callback prerequisite

IAM derives its SSO callback from IAM_PUBLIC_BASE_URL. For browser SSO through this gateway, configure the backend with:

IAM_PUBLIC_BASE_URL=https://auth.iam.teamofsilicons.com/
IAM_AUTH_BASE_URL=https://auth.iam.teamofsilicons.com/

Allowlist https://auth.iam.teamofsilicons.com/api/v1/sso/callback in WorkOS. The gateway's API_UPSTREAM stays on the backend hostname. Without this configuration the backend host will not receive the encrypted frontend cookie, and SSO cannot complete. No production setting has been changed by this implementation.

Authentication and application integration

Carbon signup requires a verified email; phone is optional, and a supplied phone must be verified or explicitly skipped. Google and Apple are shown together, with availability controlled by the backend. Both providers act as email-verification methods: the verified email signs into its existing active Carbon without a linking step or extra IAM OTP. An unregistered provider email continues explicit signup with email already verified. Accounts created through a provider retain ordinary email-code login. The approved behavior and acceptance cases are in docs/PROVIDER_EMAIL_AUTHENTICATION.md; provider configuration is internal IAM operations in deploy/aws/SOCIAL_PROVIDERS.md. Profile setup offers an available Carbon ID, display name, detected timezone, generated image and image upload. Completion signs the Carbon in automatically and prompts for first-org onboarding when no membership exists. Ordinary email signup with an already-registered email offers login.

Silicon signup collects an ID, optional 12–24-character password, custodian email, timezone and optional webhook. A generated password is revealed once. The request waits for its verified-email Carbon custodian to approve. /silicon-custody?request=… preserves that request through login/signup. Approved Silicons can sign in, edit their own profile and create an organization when their custodian allows it. Organization owners can also seed an organization-custodied Silicon or invite an existing one from a shared organization.

The official IAM CLI supports account signup and login, including IAM OTP entry. External application CLIs and backends receive only an app-bound SLT; they must never collect IAM OTPs or passwords.

Successful browser login never returns account bearer/refresh tokens to browser JavaScript. The gateway encrypts each configured account's credentials and upstream browser-session cookie into HttpOnly, SameSite=Lax cookies (Secure over HTTPS). Only opaque account handles and safe profile summaries reach the client. Refresh is server-side and serialized per account. A protected request rejected with HTTP 401 gets one refresh attempt and an identical replay; terminal refresh rejection removes the affected account, while transient errors preserve it. Renewals begin conservatively 600 seconds early to cover the backend's secret-response replay window across replicas.

Application login navigates through /auth/continue to /login. GET never grants consent or mints tokens. The picker supports Continue as Carbon or Continue as Silicon, adding accounts, and expanding/collapsing each configured account's organizations. Select exactly one account and organization. Collapse preferences persist locally. Create/join navigation returns to the pending login.

The backend's consent_required determines whether to show the critical IAM permission consent step. No OBO permission appears there. The trusted gateway uses the chosen account to submit a one-element org_ids, exact current approved_scopes, and scope_version. Every SLT and resulting app token family remains bound to that membership. A later login never expands an earlier token. Apps validate callback state and exchange SLTs on their own server with their application secret.

Application registration, configuration, webhook management, secret rotation and OBO endpoint definitions are managed through Honeycomb. IAM retains the accepted authentication records and enforces login, consent, scopes and delegated access. Old /applications, /bundles, /scope-reviews and /testing links display a handoff page with a working Honeycomb link; they do not open management forms.

OBO uses its own on-demand consent page with endpoint names, descriptions, notes, warning codes and the full dependency tree. Each provider can select a configured account and organization; omitted choices default to the originating account and organization. The gateway substitutes protected credentials for opaque account handles before submitting contexts. Only the represented user can approve. Grants remain until revoked or invalidated by current authority changes. The same access token covers every approved graph endpoint; each receiver verifies its own endpoint with IAM. The originating app alone keeps the refresh token.

An application may bind an optional callback URI and state when creating the OBO request. After a confirmed decision IAM returns the complete callback URL with authorization_id, state, and either code or error=access_denied. The frontend follows that server-bound URL. Without a callback it displays the one-use code for manual handoff. Manage grants at /console/obo?app=<app_id>. See the OBO contract.

Organization and account coverage

The UI intentionally does not expose platform-admin review, Silicon-only governance request creation, application Basic-auth token endpoints, or provider webhooks as human browser operations. Some advanced collections use a schema-driven form with JSON inputs for object arrays; field constraints and help come from the checked-in OpenAPI schema snapshot. UUID fields are explicit, not guessed from public IDs.

Correctness and security

Keeping contracts current

After backend changes, regenerate schemas and review affected screens:

ruby scripts/sync-contract.rb ../docs/openapi.yaml
npm run check
npm run build

The snapshot is a form aid, not authorization enforcement. The IAM backend remains authoritative. Review the source when OpenAPI and implementation disagree, especially step-up bindings and per-resource versions. Runtime secrets, .vercel/, dependencies and build output are excluded from Git.

Repository QA evidence is retained separately from the public manual. npm test covers URL bounds, single/batch/bundle continuation, callback encoding, permission payload integrity, and gateway CSRF rejection.

Built with SolidJS, TypeScript and Vite. The mark and IBM Plex font files are reused from the existing Silicon IAM backend assets; retain their upstream licensing when distributing.

Application permissions, reviews, and bundles

Honeycomb owns application permission requests, scope-review workflows and bundle definitions. IAM validates accepted decisions, enforces effective scopes and user consent, and retains organization bundle eligibility settings.

Bundle login remains in IAM at /login?bundle_id=org%3Ebundle. Users see the bundle identity and choose one account and organization once; the callback receives individual application SLTs in the same #slts= encoding as batch login. Every member exchanges its own token using its own secret.

The frontend links to the standalone documentation site at https://docs.iam.teamofsilicons.com. Its static build and hosting configuration are in docs-site/; it is deployed separately from the authenticated frontend.

The console and login page include Telemetry settings for a persistent browser opt-out. The gateway collects sanitized Space Station analytics and explicit events using a server-only key; see telemetry.

Typed application popup login

Applications select identity_kind=carbon|silicon and optionally display=popup on /login. The kind remains pinned through account addition and gateway redirects. Organization buttons show the logo when available and immediately continue, preserving critical IAM consent. Account administration lives behind the single Silicon IAM management link.

The gateway forwards X-IAM-Identity-Kind on organization choices and SLT issuance; it validates the encrypted account session type first. The backend independently checks the authenticated principal for single, batch and bundle issuance. The header is optional for compatibility and is included in the idempotency fingerprint when supplied.

Applications own popup creation and their callback. They must bind the selected kind to server-side state, verify it after exchanging the SLT, establish the app session, then send a token-free completion message from their own origin. The opener checks exact origin, window source and attempt ID. See the client login guide.

Install the CLI

curl -fsSL https://docs.iam.teamofsilicons.com/install.sh | sh