Automatic Ipseity authentication
When Ipseity is installed, a Website can omit spec.cms.authentication and
spec.cms.hostname. The controller defaults the CMS hostname to
cms.<spec.domain> and provisions a public OIDC client and initial administrator
membership in the Website's namespace. Explicit authentication references take
precedence and do not provision Ipseity resources.
apiVersion: cms.tlspu.com/v1alpha1
kind: Website
metadata:
name: example
namespace: websites-example
spec:
domain: example.com
description: Example website
Create the namespace first. description becomes the client's display name,
falling back to the domain. A custom spec.cms.hostname is respected in both the
CMS Ingress and the client's callback URI and allowed origin. Defaults are
applied to generated resources without writing them back to the Website spec.
Set spec.cms.enabled: false to keep a Website frontend-only, even when
Ipseity is installed. Do not combine this with a CMS hostname or authentication
reference. With no Ipseity installation, an omitted CMS remains frontend-only;
an explicit hostname or enabled: true requires authentication and blocks when
none can be provided. Losing Ipseity after automatic provisioning also blocks
CMS routing and scales its Deployment to zero until discovery recovers.
Provider discovery
Ipseity has no CRDs. The controller finds its Deployment using app: ipseity
or app.kubernetes.io/name: ipseity on the Deployment or its Pod template. It
follows same-namespace Service selectors and Ingress backends to find the public
host serving /oidc, then sets discoveryURL to https://<host>/oidc. The CMS
fetches /.well-known/openid-configuration below that base. There is no
hardcoded provider URL. Automatic provisioning requires public HTTPS endpoints.
Multiple matching Deployments or Ingress hosts block automatic provisioning
rather than selecting an arbitrary identity provider. A literal
IPSEITY_OIDC_ISSUER in the selected Deployment can identify the canonical host
among aliases, but it must match an actual discovered Ingress route. Issuer
environment variables sourced through valueFrom are not dereferenced.
These controller settings disambiguate the installation and select the initial administrator. Explicit flags take precedence over their environment fallbacks.
| Flag | Environment fallback | Default |
|---|---|---|
--ipseity-namespace |
VIKING_IPSEITY_NAMESPACE |
discover across namespaces |
--ipseity-deployment |
VIKING_IPSEITY_DEPLOYMENT |
any matching Deployment |
--ipseity-ingress |
VIKING_IPSEITY_INGRESS |
any associated Ingress |
--ipseity-admin-realm |
VIKING_IPSEITY_ADMIN_REALM |
ipseity |
--ipseity-admin-subject |
VIKING_IPSEITY_ADMIN_SUBJECT |
adrian |
Discovery is rechecked every 30 seconds for Websites without explicit
authentication. Ingress endpoint changes update the generated Secret and roll
CMS pods. Discovery/provisioning failures are reported as IpseityUnavailable
or IpseityProvisioningFailed on the Website's Ready condition.
Created records and access
The controller merges ipseity.io/realm: "true" onto the Website namespace,
preserving other labels, and creates:
| Resource | Name | Purpose |
|---|---|---|
| Client ConfigMap | ipseity-client-<domain> |
public client, consent required, client ID/name = domain, realm = Website namespace |
| Membership ConfigMap | ipseity-membership-ipseity-adrian by default |
cross-realm membership for the configured home identity, role admins |
| Authentication Secret | <domain>-ingress-oauth2 |
CMS OIDC settings and stable session-signing key |
ConfigMaps carry Ipseity's app, managed-by, entity and name labels and JSON
in data.payload. The client permits the effective CMS origin and
https://<cms-hostname>/oauth2/callback, with allowed scopes
openid profile groups roles email. The Secret selects Authorization Code
with PKCE (publicClient: "true"), requests openid profile groups roles, and
sets rolesClaim: roles, allowedRoles: admins and publishRoles: admins.
The controller generates 32 random bytes for jwtSecret, stored as base64,
and preserves that key on subsequent reconciles. Invalid existing key material
blocks provisioning rather than silently rotating sessions.
The home identity must already exist in Ipseity. With the defaults, sign in as
ipseity/adrian using that account's existing password and MFA. The membership
is created once per namespace; later administrator changes to its grants or
disabled state are preserved. Changing the controller's initial administrator
settings creates a new membership and leaves previous memberships for an
administrator to review.
The realm boundary is the namespace. Websites sharing a namespace share its realm and administrator membership, while each has a separate client ID and audience. Use separate namespaces when clients need separate realms. The target namespace must differ from the administrator's home realm. Automatic client IDs must fit Ipseity's Kubernetes name label (at most 63 characters); longer domains require explicitly configured authentication.
Retention and upgrades
Deleting a Website, disabling its CMS, changing its domain or switching to explicit authentication retains the namespace realm label and every Ipseity ConfigMap. These ConfigMaps have no Website owner references, so Kubernetes garbage collection also leaves them in place. An administrator removes obsolete clients and memberships later. Published/private PVC retention is unchanged.
The generated authentication Secret is Website-owned and is removed when obsolete or when the Website is deleted. Explicitly supplied authentication Secrets are never adopted or removed. Existing unowned credentials and client ConfigMaps are not overwritten: the automatic client records its creating Website UID in an annotation. Recreating a deleted Website under the same name produces a new UID, so an administrator must review/remove its retained client ConfigMap before automatic provisioning can recreate it. Matching existing memberships are reused without resetting their grants.
Deploy the updated Website CRD and controller RBAC before the new controller
image. The RBAC adds namespace get/patch, ConfigMap create/update, and Secret
create/update/delete; controller writes to Secrets are restricted to its own
automatic authentication resources. Review existing frontend-only Websites and
set cms.enabled: false if they should stay frontend-only when Ipseity is
detected. The local Orbit copies must match deploy/01-crd.yaml and
deploy/02-operator-rbac.yaml.
