# Local Identity Local Identity is a zero-dependency, file-based user management capability for net-kingdom bootstrap environments — systems that do not yet have (or do not need) a running Keycloak instance. ## Why it exists In net-kingdom, Keycloak is the production identity provider. But Keycloak requires a running Kubernetes cluster, a database, and a configured realm before it can authenticate anyone. This creates a bootstrapping paradox: > You need identity to set up infrastructure, but the infrastructure provides > identity. Local Identity breaks this cycle. An operator with only a Linux home directory can establish their identity, generate deterministic test users, and run dev/test applications with OIDC authentication — before any service is deployed. ## Design principles 1. **Zero dependencies** — only the Linux filesystem; no Docker, no K8s, no running services required. 2. **Derived identity** — the primary user is derived from `$USER`, `/etc/passwd` (GECOS), and a configured email address. No manual setup required for the basic case. 3. **Deterministic test users** — two test users are auto-generated from the primary user at `init` time using `N` and `+testN` suffixes: | Field | Primary | Test 1 | Test 2 | |----------|-------------|---------------------|---------------------| | username | `$USER` | `${USER}1` | `${USER}2` | | fullname | GECOS field | `+test1` | `+test2` | | email | configured | `+test1@…` | `+test2@…` | Email aliases follow the Gmail `+xxx` convention so test emails route to the operator's inbox without extra accounts. 4. **Hard isolation** — test users carry `environment: local`; production connectors reject this flag by default. Test users cannot authenticate in production without an explicit override. 5. **Minimal OIDC** — a lightweight native OIDC provider backed by the file store, for apps that require OIDC in dev/test without a running Keycloak. Tokens carry `iss: local-identity`; production systems are configured to reject this issuer. 6. **Secure by default** — `~/.local-identity/` is created with mode `700`; individual user files with mode `600`; the tool validates permissions on every startup and refuses to run if the store is world-readable. ## What it is not - **Not a production identity provider.** Local Identity is never exposed to the internet. It has no MFA. It is not hardened for public traffic. - **Not a replacement for Keycloak.** Once a cluster is operational, Keycloak is the IdP. Local Identity provides an on-ramp, not an alternative. - **Not multi-user.** Local Identity is single-operator: one primary user derived from the Linux session, plus generated test users. - **Not an LDAP/AD/Entra bridge.** Enterprise federation is handled by Keycloak. See EP-NK-001 in the State Hub. - **No MFA.** Second factors are out of scope; this is intentionally minimal. ## User schema Users are stored as YAML files under `~/.local-identity/users/`: ```yaml # ~/.local-identity/users/tegwick.yaml schema_version: "1" username: tegwick fullname: "Bernd Worsch" email: "bernd.worsch@gmail.com" environment: local # never "production" for local-identity users generated: false # true for auto-generated test users production_identity: # optional: maps this user to a production identity username: tegwick realm: net-kingdom ``` Test users are generated at `init` time and stored alongside: ```yaml # ~/.local-identity/users/tegwick1.yaml schema_version: "1" username: tegwick1 fullname: "Bernd Worsch+test1" email: "bernd.worsch+test1@gmail.com" environment: local generated: true source_user: tegwick production_identity: # optional: can map to a test/staging account username: tegwick-test1 realm: net-kingdom ``` ## Sandbox → production mapping Each user file can optionally carry a `production_identity` block. When an entity owned by a local-identity user needs to be transferred to a production environment (e.g. a resource created during local development), the mapping provides the correct production user ID. `local-identity export ` produces a Keycloak-compatible user JSON that respects this mapping. The schema is validated against the Keycloak user representation to prevent silent drift. ## CLI reference ``` local-identity init # derive primary user, generate test users local-identity list # list all users in the store local-identity show # display user file local-identity export # emit Keycloak-compatible JSON local-identity security-check # validate filesystem permissions and config ``` ## OIDC provider (Stage 3) When running `local-identity serve`, a minimal OIDC Authorization Code flow server starts on localhost. It supports: - `GET /.well-known/openid-configuration` — discovery document - Authorization endpoint, token endpoint, userinfo endpoint - JWT tokens with `iss: local-identity` (hard-coded; production systems reject this issuer by default) - Auto-generated self-signed TLS certificate This allows dev/test applications to use standard OIDC libraries against Local Identity without any Keycloak dependency. **Security note:** the OIDC server binds to `127.0.0.1` only. Never expose it on a public interface. ## Risks and mitigations | Risk | Mitigation | |------|------------| | World-readable credential files | `~/.local-identity/` mode `700`; startup check fails loudly | | Test users leaking into production | `environment: local` flag; production connectors reject by default | | Local Identity tokens accepted in production | `iss: local-identity`; configure production Keycloak to reject this issuer | | File schema drifting from Keycloak model | `export` command validates against Keycloak representation; schema is versioned | | Bootstrap store becoming a long-lived crutch | Explicit scope limit: once Keycloak is operational, migrate and stop using Local Identity | ## Relationship to the SSO platform Local Identity is a complementary workstream to the SSO & MFA Platform (NK-WP-0001). The SSO platform provides production-grade identity; Local Identity provides the bootstrap path that allows the SSO platform itself to be set up and tested. When the Keycloak realm (NK-WP-0001 T06) is operational, primary and test users can be exported from Local Identity into Keycloak using `local-identity export` and the Keycloak admin API. Implementation: see [NK-WP-0002](../workplans/NK-WP-0002-local-identity.md).