Backstage Branding
The sidebar logo and a curated set of theme colors are driven by app-config rather than hardcoded in the frontend build. This lets you override kubriX's default branding per customer through Helm values and a ConfigMap, without rebuilding the Backstage image. Only a pod restart is needed to pick up new values.
What's Configurable
| Key | Purpose |
|---|---|
kubrix.branding.fullLogo | Sidebar logo, expanded state |
kubrix.branding.iconLogo | Sidebar logo, collapsed state |
kubrix.theme.primaryColor | Links, active nav item, sidebar gradient's bottom stop |
kubrix.theme.secondaryColor | Secondary accent |
kubrix.theme.sidebarGradientFrom | Sidebar gradient, top stop |
kubrix.theme.sidebarGradientTo | Sidebar gradient, bottom stop (defaults to primaryColor if unset) |
kubrix.theme.sidebarIndicator | Active nav item indicator color |
kubrix.theme.pageThemeColors | Page header gradient (2 colors), defaults to [primaryColor, '#cc02fe'] |
kubrix.theme.pageShape | Page header decoration: wave, wave2, round, square, or flat (no decoration) |
Everything not listed here (typography, component-level style overrides) stays fixed in code. Only the values above are meant to vary per customer.
If a key is left unset, kubriX's own branding (logo and blue color scheme) is used. This is the fallback baked into the app, not something that needs to be set explicitly for the default kubriX look.
Example
appConfig:
kubrix:
branding:
fullLogo: 'https://cdn.example.com/customer/logo-full.png'
iconLogo: 'https://cdn.example.com/customer/logo-icon.png'
theme:
primaryColor: '#002060'
secondaryColor: '#f07000'
sidebarGradientFrom: '#1a4c8c'
sidebarIndicator: '#f07000'
pageShape: 'flat'
pageShape: 'flat' is the safer default for arbitrary customer colors. The decorative shapes (wave/wave2/round/square) overlay a translucent white pattern on the header gradient, which only reliably looks good with hand-picked color pairs. With colors nobody curated in advance, flat avoids muddy blends where the two colors are visually distinct hues (e.g. blue and orange).
Logo Requirements
-
Any raster format (PNG, JPG) or SVG works, as a Base64 data URI or an external
httpsURL. -
SVG files must have a
viewBoxor explicitwidth/height. The logo renders as a plain<img>, which needs intrinsic dimensions to size an SVG correctly. -
Aspect ratio doesn't need to be square: logos are fit with
object-fit: contain, so wide or tall logos scale down without cropping or distortion. -
Height is fixed (80px expanded, 28px collapsed); width is automatically capped to the available sidebar space.
-
External
httpsURLs require the host to be allowed inbackend.csp.img-src(the default CSP only permits'self'anddata:):appConfig:
backend:
csp:
img-src: ["'self'", 'data:', 'https://cdn.example.com']To allow any
httpshost rather than a specific one, use'https:'instead of a fixed domain. Scoping it to the actual asset host is the safer option when the source is known ahead of time.
Configuring an Image via ConfigMap (Base64)
To embed a logo directly in Helm values instead of hosting it externally, convert the image file to a Base64 string and use it as a data: URI.
Encode the file
# macOS
base64 -i logo.png | tr -d '\n'
# Linux
base64 -w0 logo.png
Copy the output and build the data URI, matching the image's actual MIME type:
data:image/png;base64,<paste-the-base64-output-here>
Set it in values
appConfig:
kubrix:
branding:
fullLogo: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...'
Use image/png, image/jpeg, or image/svg+xml as the MIME type, matching the source file. On the next Helm upgrade, this value is rendered straight into the app-config ConfigMap, and the frontend reads it back out as the src of the sidebar logo <img> element. No separate image hosting or extra ConfigMap mount is involved: the encoded string is just another app-config value.
Size Limit
Kubernetes caps a single ConfigMap at 1 MiB total, not per key, the whole object. If branding is delivered as part of the app-config ConfigMap, both logos plus the rest of the rendered config all count against that same limit. Base64 also adds roughly 33% overhead over the raw image bytes.
Going over the limit doesn't degrade gracefully: the ConfigMap fails to apply and the Helm deploy fails outright.
Guidance:
- Keep each logo's source image under roughly 150-200 KB. That comfortably leaves room for the rest of
app-configin the same ConfigMap. - For anything larger, such as a hi-res marketing logo or a photo-based mark, use the external
httpsURL form instead of Base64. Only a short string goes into the ConfigMap either way, so the customer's asset host (their own CDN, a static bucket, etc.) carries the actual image weight.
Default Fallback
If appConfig.kubrix.branding / appConfig.kubrix.theme aren't set in values, the app falls back to kubriX's own logo and color scheme, hardcoded in the frontend as the default. No action is needed to get that default look; this customization surface only matters when a deployment needs to reflect a specific customer's brand.