Compare commits

...
Author SHA1 Message Date
Cedric VerstraetenandClaude Opus 5.5 9695209b0e feat(hub): configurable hub-api session lifetime, hub-api v1.11.42 (0.186.0)
Add kerberoshub.api.session.{accessTokenTimeout,idleTimeout,maxLifetime}
(defaults 15m / 12h / 24h), passed to hub-api as ACCESS_TOKEN_TIMEOUT,
SESSION_IDLE_TIMEOUT and SESSION_MAX_LIFETIME, and default hub-api to
v1.11.42, which enforces them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 09:07:56 +00:00
Cédric Verstraeten 3dec5944f2 Merge pull request #242 from kerberos-io/feat/hub-trusted-registry-own-images
feat(hub): trusted-registry reports only UUG.AI images (0.185.1)
2026-11-12 10:06:24 +01:00
Cédric VerstraetenandClaude Opus 5.5 02ab752118 feat(hub): trusted-registry reports only UUG.AI images (0.185.1)
trusted-registry matched every pod in the namespace and reported
workloads the chart doesn't deploy (agents, cert-manager solvers, jobs).
Report only UUG.AI images (uugai/, uug-ai/) not pulled from ghcr.io/uug-ai.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-12 09:03:47 +00:00
5 changed files with 44 additions and 19 deletions
+1 -1
View File
@@ -16,7 +16,7 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.185.0
version: 0.186.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
+11 -6
View File
@@ -367,11 +367,13 @@ Since chart **`0.184.0`** only `ghcr.io/uug-ai` images are trusted:
`ghcr.io/uug-ai/<image>` repository only. Images that are not signed or
hardened yet stay in `Audit` (the tables mark them), so they show up as
failures in Policy Reporter without ever being blocked;
- `trusted-registry.yaml` (category **`Image registry`**, `Audit`) reports every
container image from any other registry or organisation. Since **`0.185.0`**
the only one the chart can still deploy is the third-party
`quay.io/oauth2-proxy/oauth2-proxy` (pin it to a version or digest rather
than `:latest`).
- `trusted-registry.yaml` (category **`Image registry`**, `Audit`) reports a
UUG.AI image (`uugai/...`, or a `uugai/` or `uug-ai/` organisation on any
registry) that is not pulled from `ghcr.io/uug-ai`. Since **`0.185.1`** it
ignores every other image in the namespace: workloads the chart doesn't
deploy (agents, cert-manager solvers, other tools) and the third-party
`quay.io/oauth2-proxy/oauth2-proxy` (pin that one to a version or digest
rather than `:latest`).
Since chart **`0.185.0`** every UUG.AI image defaults to a signed, hardened
release with the attestation (Admin `v1.4.6`, hub-reactivatesubscriptions
@@ -860,11 +862,14 @@ kerberospipeline:
| `kerberoshub.serviceAccount.labels` | Labels applied to `kerberoshub.serviceAccount` resources. | `""` |
| `kerberoshub.api.repository` | The Docker registry where the Kerberos Hub API container is hosted. | `"ghcr.io/uug-ai/hub-api"` |
| `kerberoshub.api.pullPolicy` | The Docker registry pull policy. | `"IfNotPresent"` |
| `kerberoshub.api.tag` | The Docker image tag/version. | `"v1.11.41"` |
| `kerberoshub.api.tag` | The Docker image tag/version. | `"v1.11.42"` |
| `kerberoshub.api.replicas` | The number of pods/replicas running for the Kerberos Hub API deployment. | `2` |
| `kerberoshub.api.audit.enabled` | Enable audit publishing from Hub API when global auditing is enabled. | `true` |
| `kerberoshub.api.logLevel` | Log verbosity level for `kerberoshub.api`. | `"info"` |
| `kerberoshub.api.jwtSecret` | A secret that is for generating JWT tokens. | `"this-is-a-secret-please-change-to-random-string"` |
| `kerberoshub.api.session.accessTokenTimeout` | Lifetime of one access token (Go duration). The frontend renews it silently while the session is valid. | `"15m"` |
| `kerberoshub.api.session.idleTimeout` | A session that is not used for this long ends (lifetime of the refresh token). | `"12h"` |
| `kerberoshub.api.session.maxLifetime` | Hard session limit counted from login; refreshing never extends a session past it. | `"24h"` |
| `kerberoshub.api.schema` | The protocol to serve the Kerberos Hub API, `'http'` or `'https'`. | `"https"` |
| `kerberoshub.api.url` | The Kerberos Hub API ingress to access the API. | `"api.yourdomain.com"` |
| `kerberoshub.api.corsAllowedOrigins` | Additional complete HTTP(S) origins allowed to call the Hub API. Configured frontend origins remain allowed automatically. | `[]` |
@@ -303,6 +303,12 @@ spec:
value: "{{ .Values.kerberoshub.api.schema }}://{{ .Values.kerberoshub.api.url }}"
- name: PUBLIC_URL
value: "{{ .Values.kerberoshub.frontend.schema }}://{{ .Values.kerberoshub.frontend.url }}"
- name: ACCESS_TOKEN_TIMEOUT
value: {{ .Values.kerberoshub.api.session.accessTokenTimeout | quote }}
- name: SESSION_IDLE_TIMEOUT
value: {{ .Values.kerberoshub.api.session.idleTimeout | quote }}
- name: SESSION_MAX_LIFETIME
value: {{ .Values.kerberoshub.api.session.maxLifetime | quote }}
- name: REFRESH_COOKIE_SECURE
value: {{ eq .Values.kerberoshub.api.schema "https" | quote }}
{{- $corsOrigins := list (printf "%s://%s" .Values.kerberoshub.frontend.schema .Values.kerberoshub.frontend.url) }}
@@ -1,9 +1,11 @@
{{- /*
Only images from ghcr.io/uug-ai are trusted: report every container, init
container and ephemeral container image from any other registry or
organisation (Docker Hub, quay.io, ...). Signature and hardening are checked per
image by the *-signed-images / *-hardened-images policies, which match
ghcr.io/uug-ai images only.
UUG.AI images are trusted only from ghcr.io/uug-ai: report a container, init
container or ephemeral container image that is a UUG.AI image (uugai/... on
Docker Hub, or any registry's uugai/ or uug-ai/ organisation) pulled from
anywhere else. Other images in the namespace (agents, cert-manager solvers,
third-party tools) are not the chart's to vouch for and are ignored. Signature
and hardening are checked per image by the *-signed-images / *-hardened-images
policies, which match ghcr.io/uug-ai images only.
A namespaced Policy, so it applies only to the release namespace.
Rendered only when imageVerification.enabled is true and Kyverno is installed.
*/ -}}
@@ -13,15 +15,13 @@ kind: Policy
metadata:
name: trusted-registry
annotations:
policies.kyverno.io/title: Images must come from ghcr.io/uug-ai
policies.kyverno.io/title: UUG.AI images must come from ghcr.io/uug-ai
policies.kyverno.io/category: Image registry
policies.kyverno.io/severity: high
policies.kyverno.io/subject: Pod
spec:
# Reports images from other registries without blocking them, even when
# imageVerification.validationFailureAction is Enforce: some images the chart
# can deploy are not on ghcr.io/uug-ai yet (see README). Switch to the
# configured value once every image is.
# Reports UUG.AI images from other registries without blocking them, even
# when imageVerification.validationFailureAction is Enforce.
validationFailureAction: Audit
# Kyverno's default (Fail) would stop pods starting while Kyverno is down.
failurePolicy: Ignore
@@ -33,12 +33,21 @@ spec:
kinds:
- Pod
validate:
message: "Every container image must come from the trusted registry ghcr.io/uug-ai/."
message: "UUG.AI images must come from the trusted registry ghcr.io/uug-ai/."
foreach:
- list: "request.object.spec.[containers, initContainers, ephemeralContainers][]"
deny:
conditions:
all:
# A UUG.AI image: Docker Hub uugai/..., or a uugai/ or uug-ai/
# organisation on any registry ...
- key: "{{`{{ element.image }}`}}"
operator: AnyIn
value:
- "uugai/*"
- "*/uugai/*"
- "*/uug-ai/*"
# ... that is not pulled from ghcr.io/uug-ai.
- key: "{{`{{ element.image }}`}}"
operator: NotEquals
value: "ghcr.io/uug-ai/*"
+6 -1
View File
@@ -381,7 +381,7 @@ kerberoshub:
api:
repository: ghcr.io/uug-ai/hub-api
pullPolicy: IfNotPresent
tag: "v1.11.41"
tag: "v1.11.42"
replicas: 2
podSecurityContext:
fsGroup: 65532
@@ -410,6 +410,11 @@ kerberoshub:
serviceEnabled: true
logLevel: "info" # possible values: trace, debug, info, warn, error
jwtSecret: "this-is-a-secret-please-change-to-random-string" # change to a random value, this is for generating JWT tokens.
# How long a user stays signed in (Go durations, e.g. "15m", "12h").
session:
accessTokenTimeout: "15m" # Lifetime of one access token; the frontend renews it silently.
idleTimeout: "12h" # A session that is not used for this long ends.
maxLifetime: "24h" # Hard limit counted from login; the user must sign in again after it.
schema: "https"
url: "api.yourdomain.com"
# Additional complete HTTP(S) origins allowed to call the Hub API.