White-Label Branding
White-Label Branding¶
With the right license, a self-hosted Huitzo deployment can be fully white-labeled: the product name, accent colors, fonts, logos, favicon, and transactional emails change across the Hub, hosted dashboards, login screen, and emails — driven entirely by a branding manifest you mount at the deployment root. No code, no rebuild: every brand is a data directory.
The design and security model are fixed by ADR-015 (the manifest) and ADR-016 (the license gate). This guide is the operator how-to.
Two requirements¶
White-label takes effect only when both are true:
- A branding directory is mounted read-only at
/etc/huitzo/branding(configurable viaHUITZO_BRANDING_PATH). - The deployment's license grants
white_label(thefeaturesarray of the signed license file — see ADR-016). Ask for white-label in the license request; Core Preview (Demo/POC) licenses cannot carry it (Request a license).
If either is missing — no directory, an invalid manifest, or a license without
white_label — the deployment serves the baked-in Huitzo defaults and logs a
warning. Branding never takes a deployment down (fail-to-default, the inverse
of the license hard gate). The mismatch ("manifest present but unlicensed") is
surfaced in GET /api/v1/license/status so you can see why a brand did not take.
The branding directory¶
branding/
├── branding.yaml # the manifest (schema_version: 1)
└── assets/
├── logo.png # primary wordmark (light surfaces)
├── logo-dark.png # optional dark-surface variant
├── favicon.svg # optional browser-tab / theme icon
├── email-logo.png # optional logo embedded in emails
└── *.woff2 # optional bundled fonts
A complete, working example ships at
examples/branding/harborview-mutual/
(a fictional brand with original assets).
Manifest reference (branding.yaml)¶
| Section | Field | Notes |
|---|---|---|
schema_version |
— | Required; must equal 1. |
product |
name |
Required brand string — replaces "Huitzo Hub" everywhere. |
product |
tagline |
Optional; the login-screen subtitle. |
product |
support_url |
Optional http(s) URL — replaces the huitzo.com support link. |
colors.dark / colors.light |
--color-* (without the --) |
Any subset of the 24 brand-color tokens, per theme. Values are hex (#RRGGBB / #RRGGBBAA). |
fonts.sans / fonts.mono |
family, files |
Optional font-family override (prepended to the IBM Plex stack) + optional bundled .woff2 under assets/. |
assets |
logo, logo_dark, favicon, email_logo |
Optional bare filenames resolved inside assets/. |
The token vocabulary is the entire contract. Only the 24 --color-* tokens
and the two font-family tokens are overridable (26 total). Layout, spacing,
radius, type scale, and z-index are not brand-tunable — anything outside the
allowlist is rejected at validation time. There is no custom-CSS escape hatch.
Asset rules (enforced)¶
- Logos and the email logo are raster only (
.png/.webp); the favicon may be.svg/.png/.ico. An SVG favicon is sanitized (active content stripped) and served under a restrictive Content-Security-Policy. - Filenames are bare (no paths /
..); content-type is pinned from the key; size caps apply (logo ≤ 512 KB, email logo ≤ 256 KB, favicon ≤ 64 KB, each woff2 ≤ 256 KB). - An invalid manifest is rejected whole — a deployment never renders a half-applied brand.
Validate before you deploy¶
Run the CLI validator (offline; CI-friendly exit codes) before bringing the deployment up:
huitzo branding validate ./branding
# exit 0 = valid, 1 = errors (use --json for a machine-readable report)
It checks the same schema and asset rules the backend enforces at load time, so you catch a typo before the deployment silently falls back to defaults. See the CLI reference.
Mount it¶
Place the branding/ directory next to your compose file and mount it read-only
at /etc/huitzo/branding on the backend service — the same shape as the license
file. The compose baseline already includes the optional mount:
# docker-compose.yml (backend service) — already present
volumes:
- ./branding:/etc/huitzo/branding:ro
Drop in (or remove) the branding/ directory and restart the backend to apply.
An absent or empty directory is the normal default and serves Huitzo branding.
What changes¶
| Surface | Effect |
|---|---|
| Login screen | Product name, tagline, logo, support link, favicon, accent. |
| Hub chrome | Header wordmark, page title, theme color, accent across the UI. |
Hosted dashboards (/d/{slug}) |
Inherit the Hub's brand tokens automatically (the SDK aliases the Hub token names). |
| Transactional emails | Welcome / password-reset wordmark, accent, optional logo, footer. |
Notes¶
- Full mark removal, no forced attribution. White-label means the Huitzo marks are removed; any "powered by" requirement is a contract term, not a runtime flag.
- Per-tenant branding is deferred. v1 is deployment-level (one brand per deployment). The same schema becomes a per-tenant overlay later.
- Demos of a prospect's brand keep the prospect's assets outside this repository — see the branded-demo runbook.
Support and contacts¶
| Need | Contact |
|---|---|
| License requests and renewals | partners.huitzo.ai (partner administrators) |
| Install questions, licensing questions, anything not covered here | Your Huitzo partner contact, or [email protected] |
| Legal notices | [email protected] |
| Security vulnerabilities | [email protected] |