Skip to content

feat(authup): mount an operator console theme - #5

Merged
tada5hi merged 3 commits into
masterfrom
feat/theme-configmap
Aug 4, 2026
Merged

feat(authup): mount an operator console theme#5
tada5hi merged 3 commits into
masterfrom
feat/theme-configmap

Conversation

@tada5hi

@tada5hi tada5hi commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Rebranding the served consoles becomes a values change instead of a hand-written ConfigMap plus two volume stanzas.

server:
  theme:
    enabled: true
    files:
      theme.json: |
        {"version": 1, "tokens": {"--authup-periwinkle": "#c0392b"}}
      assets/theme.css: |
        .a-auth-shell-card { border-radius: 2px; }

The volume mounts at /etc/authup/theme, and THEME_DIRECTORY_PATH / THEME_FRAGMENTS_ENABLED are derived from it. Values UX mirrors the existing server.provisioning: files map, existingConfigMap, tpl-rendered content.

Pairs with authup/authup#3385, which adds the server side.

Subdirectories in a flat ConfigMap

A ConfigMap key cannot contain /, but the theme layout has assets/ and fragments/. Keys are flattened to __ and projected back by the volume's items list, so the operator writes assets/theme.css and never sees the encoding:

data:
  assets__theme.css: ...
---
items:
  - key: assets__theme.css
    path: assets/theme.css

existingConfigMapItems exposes the same projection for an existing ConfigMap, which is also the route for binary assets (a binaryData logo) that a values map cannot express.

The migration Job

The theme volume is deliberately not part of the shared authup.server.volumes helper. The migration Job is a pre-upgrade hook, and hooks precede regular resources, so on the upgrade that first enables theming it would reference a ConfigMap that does not exist yet and hang. A migration run has no use for the theme either way.

The same shape exists today for server.provisioning. I left it alone rather than widening this PR, but it is worth a follow-up.

Render-time fails

Theming's dominant failure mode is a page that looks exactly like an un-themed page, so nothing may render silently inert. In the chart's existing fail-loud style:

  • enabled with neither files nor existingConfigMap
  • files and existingConfigMap together (the latter would win, the former vanish)
  • existingConfigMapItems without existingConfigMap
  • file keys that are absolute, contain .., or contain the reserved __

Notes

Whole-volume projection rather than subPath, because a subPath mount is frozen until the pod restarts and would destroy authup's live theme reload.

Requires an authup image supporting THEME_DIRECTORY_PATH; older images ignore the variable, so enabling it against one is inert rather than broken.

Verification

  • make test green: helm lint, all 6 ci values files render, values-coverage 284 paths
  • New ci/theme-values.yaml scenario, so the kind matrix rolls the mount out live
  • All four fail paths exercised by hand
  • README and values.schema.json regenerated, no drift
  • With the theme off the rendered manifests are byte-identical apart from the randomly generated passwords

Summary by CodeRabbit

  • New Features

    • Added optional server theme support for Authup deployments.
    • Themes can be provided through inline files or an existing ConfigMap.
    • Added support for projecting theme assets into subdirectories.
    • Added optional HTML head fragments for console pages.
    • Theme changes automatically trigger deployment updates.
  • Validation

    • Added configuration checks for invalid paths, conflicting sources, and incomplete theme settings.
  • Documentation

    • Documented the new server theme configuration options and included an example configuration.

Copilot AI lite review requested due to automatic review settings August 4, 2026 07:19
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The chart adds server theme configuration from inline files or an existing ConfigMap. It validates theme sources and paths, creates or mounts theme resources, exports theme environment settings, and supports optional raw head fragments.

Changes

Server theme support

Layer / File(s) Summary
Theme configuration contract
charts/authup/values.schema.json, charts/authup/values.yaml, charts/authup/ci/theme-values.yaml, charts/authup/README.md
Defines server theme values for inline files, existing ConfigMaps, projected paths, fragments, and binary assets.
Theme validation and environment wiring
charts/authup/templates/_server-env.tpl
Validates theme sources and paths. Adds theme environment variables, reserved keys, mount detection, and volume helpers.
Theme ConfigMap and deployment mounts
charts/authup/templates/server/configmap-theme.yaml, charts/authup/templates/server/deployment.yaml
Creates inline theme ConfigMaps and conditionally adds checksum tracking, volumes, and mounts to the server deployment.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: copilot

Sequence Diagram(s)

sequenceDiagram
  participant HelmValues
  participant ThemeValidation
  participant ThemeConfigMap
  participant ServerDeployment
  participant AuthupServer
  HelmValues->>ThemeValidation: theme source configuration
  ThemeValidation->>ThemeConfigMap: validate and render inline files
  ThemeValidation->>ServerDeployment: theme mount and environment settings
  ThemeConfigMap->>ServerDeployment: ConfigMap volume source
  ServerDeployment->>AuthupServer: mounted theme files and theme environment
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding support to mount an Authup operator console theme.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/theme-configmap

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@charts/authup/templates/_server-env.tpl`:
- Around line 230-239: Validate each $path in the server.theme.files loop before
generating ConfigMap entries, rejecting empty paths or any path whose encoded
themeConfigMapKey contains characters outside Kubernetes’ allowed [A-Za-z0-9._-]
set. Preserve the existing absolute-path, traversal, and "__" checks, and add
render coverage for spaces, colons, and empty paths.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c9093b68-ca07-4bb8-908a-57e6db47a85e

📥 Commits

Reviewing files that changed from the base of the PR and between 1100904 and e0d2adf.

📒 Files selected for processing (7)
  • charts/authup/README.md
  • charts/authup/ci/theme-values.yaml
  • charts/authup/templates/_server-env.tpl
  • charts/authup/templates/server/configmap-theme.yaml
  • charts/authup/templates/server/deployment.yaml
  • charts/authup/values.schema.json
  • charts/authup/values.yaml

Comment thread charts/authup/templates/_server-env.tpl

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class chart support for mounting an operator-managed Authup console theme via values, so console rebranding becomes a values-only change (inline files or an existing ConfigMap) rather than bespoke manifests and manual volume wiring.

Changes:

  • Introduces server.theme values (inline file map and/or existing ConfigMap projection) and corresponding render-time validation/fail-loud behavior.
  • Wires theme mounting into the server Deployment (volumes/volumeMounts + checksum for inline theme ConfigMap) and sets theme-related env vars.
  • Updates generated docs/schema and adds a CI render scenario (ci/theme-values.yaml) to exercise the feature.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
charts/authup/values.yaml Adds new server.theme values surface (files/existing ConfigMap/items/fragments flag).
charts/authup/values.schema.json Regenerates schema to include server.theme fields.
charts/authup/templates/server/deployment.yaml Adds theme checksum + conditionally appends theme volumes/volumeMounts.
charts/authup/templates/server/configmap-theme.yaml New inline theme ConfigMap (with key-flattening for subdirectories).
charts/authup/templates/_server-env.tpl Adds theme validation + env wiring + theme volume helpers.
charts/authup/README.md Regenerates parameter table to document server.theme.*.
charts/authup/ci/theme-values.yaml Adds CI values case covering inline theme files + fragments.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread charts/authup/templates/_server-env.tpl
@tada5hi

tada5hi commented Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai pause

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
✅ Action performed

Reviews paused.

tada5hi added a commit that referenced this pull request Aug 4, 2026
Two review findings on #5.

The path -> ConfigMap key flattening only replaced "/", so a key carrying
a space, a colon, an "@" or a leading dot produced a data key outside
Kubernetes' ^[A-Za-z0-9._-]+$ and failed at apply time with a validation
error rather than at render time. An empty key did the same. The path is
now checked against the character set the server's own asset handler
accepts, so the chart rejects at render time exactly what the server
would 404 at request time.

THEME_DIRECTORY_PATH / THEME_FRAGMENTS_ENABLED moved out of
authup.server.configEnv into a deployment-only block, for the same reason
the theme volume is not in authup.server.volumes: the migration Job
inlines configEnv, so it was being told about a theme directory it
deliberately does not mount. Nothing reads it there today (the migration
command builds only the config and logger modules, never the http one),
so this is consistency rather than a live failure, but the env should not
describe a pod that does not exist.

THEME_* stays in configEnv's reserved-key list, so a `server.config`
entry still cannot emit a duplicate key into the same ConfigMap.
tada5hi added 2 commits August 4, 2026 09:38
Adds `server.theme`, so rebranding the served consoles is a values change
rather than a hand-written ConfigMap plus two volume stanzas:

    server:
      theme:
        enabled: true
        files:
          theme.json: |
            {"version": 1, "tokens": {"--authup-periwinkle": "#c0392b"}}
          assets/theme.css: |
            .a-auth-shell-card { border-radius: 2px; }

The volume is mounted at /etc/authup/theme and THEME_DIRECTORY_PATH plus
THEME_FRAGMENTS_ENABLED are derived from it, mirroring the existing
`server.provisioning` UX (files map, existingConfigMap, tpl-rendered
content).

A ConfigMap key cannot contain "/", but the theme layout has
subdirectories, so keys are flattened to "__" and projected back by the
volume's items list. The operator writes "assets/theme.css" and never
sees the encoding. `existingConfigMapItems` exposes the same projection
for an existing ConfigMap, which is also the route for binary assets
(binaryData) that a values map cannot express.

The theme volume is deliberately NOT part of the shared
authup.server.volumes helper. The migration Job is a pre-upgrade hook and
hooks precede regular resources, so on the upgrade that first enables
theming it would reference a ConfigMap that does not exist yet and hang.
A migration run has no use for the theme either way. (The same shape
exists for `server.provisioning`, which this change deliberately leaves
alone.)

Render-time fails, in the chart's fail-loud style: enabled with no
content, files and existingConfigMap together, existingConfigMapItems
without existingConfigMap, and file keys that are absolute, traverse out
of the theme root, or contain the reserved "__". Theming's dominant
failure mode is a page that looks exactly like an un-themed page, so none
of these may render silently inert.

Whole-volume projection rather than subPath: a subPath mount is frozen
until the pod restarts, which would destroy authup's live theme reload.

Requires an authup image that supports THEME_DIRECTORY_PATH. Older images
ignore the variable, so enabling this against one is inert rather than
broken. With the theme off the rendered manifests are unchanged.
Two review findings on #5.

The path -> ConfigMap key flattening only replaced "/", so a key carrying
a space, a colon, an "@" or a leading dot produced a data key outside
Kubernetes' ^[A-Za-z0-9._-]+$ and failed at apply time with a validation
error rather than at render time. An empty key did the same. The path is
now checked against the character set the server's own asset handler
accepts, so the chart rejects at render time exactly what the server
would 404 at request time.

THEME_DIRECTORY_PATH / THEME_FRAGMENTS_ENABLED moved out of
authup.server.configEnv into a deployment-only block, for the same reason
the theme volume is not in authup.server.volumes: the migration Job
inlines configEnv, so it was being told about a theme directory it
deliberately does not mount. Nothing reads it there today (the migration
command builds only the config and logger modules, never the http one),
so this is consistency rather than a live failure, but the env should not
describe a pod that does not exist.

THEME_* stays in configEnv's reserved-key list, so a `server.config`
entry still cannot emit a duplicate key into the same ConfigMap.
THEME_* moved out of authup.server.configEnv so the migration Job would
not inherit env for a volume it does not mount. That also dropped it out
of checksum/env, which hashes configEnv alone: flipping
server.theme.fragmentsEnabled rewrote the server env ConfigMap without
rolling the pods, and envFrom is snapshotted at container start, so
running pods kept the stale value indefinitely.

The annotation now hashes both halves of that ConfigMap. With the theme
disabled the hash is unchanged, so non-theme releases do not roll on
upgrade.
@tada5hi
tada5hi merged commit 74942eb into master Aug 4, 2026
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants