OpenDepot Workshop Administration¶
This page covers deployment, authentication, routing, and visibility controls for OpenDepot Workshop. For the user-facing Workshop and its Registry Explorer and resource details, see the OpenDepot Workshop guide.
Routing Architecture¶
When ui.enabled: true, OpenDepot deploys a Next.js frontend alongside the server. NGINX runs inside the UI pod and splits traffic between the registry protocol server and the browser UI:
| Path prefix | Destination |
|---|---|
/opendepot/* | Server — registry protocol and browse API |
/.well-known/* | Server — service discovery |
/ (all other paths) | Next.js UI at port 3000 |
When ui.ingress.enabled: true, the Kubernetes Ingress applies the same split-path rules at the load balancer. The /opendepot and /.well-known paths route directly to the server Service; all other paths go to the ui Service. NGINX re-proxies browser-originated same-origin API calls from the UI back to the server.
When server.ingress.istio.enabled: true and ui.enabled: true, the Istio VirtualService template automatically adds the same split HTTP match rules. No additional Istio configuration is required.
Warning
When ui.enabled: true, the server-ingress.yaml template is automatically disabled. If you were previously routing directly through the server Ingress, migrate to ui.ingress before enabling the UI.
Local Quick Start with Tilt¶
The fastest way to try OpenDepot Workshop is the repository's Tilt environment. It creates or reuses a local Kind cluster, builds the complete stack, configures Dex OIDC, generates development secrets, and enables live updates.
Install the local quickstart prerequisites, then run from the repository root:
Wait for the ui resource to become ready in the Tilt dashboard, then open https://opendepot.localtest.me:8443. Sign in as dev@example.com with the value of OPENDEPOT_DEV_PASSWORD.
Create sample resources from the Tilt dashboard or run:
The sample GroupBinding grants the local user access to the seeded resources. Refresh OpenDepot Workshop to browse version metadata, READMEs, and scan findings.
Stop Tilt with Ctrl+C, then remove the deployed resources while preserving the local cluster and image registry:
Enabling the UI¶
Create the session secret¶
The UI uses encrypted server-side session cookies. Provide a secret of at least 32 characters before deploying:
kubectl create secret generic ui-session-secret \
--from-literal=sessionPassword=$(openssl rand -base64 32) \
-n opendepot-system
Register an OIDC client¶
When ui.oidc.enabled: true, the UI uses the OIDC authorization code flow to authenticate users. The groups claim from the resulting token is matched against GroupBinding resources. Skip this step if you only need anonymous browsing.
Add a staticClient to your Dex configuration:
dex:
config:
staticClients:
- id: opendepot-ui
name: OpenDepot UI
secretEnv: OPENDEPOT_UI_CLIENT_SECRET
redirectURIs:
- https://opendepot.example.com/auth/callback
responseTypes:
- code
grantTypes:
- authorization_code
Create the client secret:
kubectl create secret generic ui-oidc-secret \
--from-literal=clientSecret=<your-client-secret> \
-n opendepot-system
Set Helm values¶
At minimum:
ui:
enabled: true
sessionPasswordSecretName: ui-session-secret
ingress:
enabled: true
className: nginx
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
hosts:
- host: opendepot.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: opendepot-tls
hosts:
- opendepot.example.com
To enable OIDC login, add:
ui:
oidc:
enabled: true
issuerUrl: https://dex.example.com/dex
clientId: opendepot-ui
clientSecretName: ui-oidc-secret
scopes: "openid profile email groups"
callbackPath: /auth/callback
Developer token input — never enable in production
ui.auth.devTokenInput.enabled: true renders a token input field in the Sidebar for testing the UI against a live cluster. The default is false.
See Helm Chart — UI Configuration for the full ui.* Helm values reference.
Apply the chart¶
Public Visibility Labels¶
By default, browse endpoints return only resources explicitly marked as public:
| Label | Applied to | Effect |
|---|---|---|
opendepot.defdev.io/public: "true" | Kubernetes Namespace | Marks the namespace as publicly discoverable |
opendepot.defdev.io/public: "true" | Module or Provider | Marks the resource as publicly viewable |
Both labels must be present for unauthenticated callers to see a resource.
Browse Visibility Rules¶
| Caller | Resources visible |
|---|---|
| Unauthenticated in OIDC mode with anonymous access disabled | 401 Unauthorized |
| Unauthenticated in non-OIDC or anonymous mode | Public namespace and public resources |
OIDC-authenticated without a matching GroupBinding | Public namespace and public resources |
OIDC-authenticated with a matching GroupBinding | Public resources plus resources allowed by the binding |
anonymousAuth: true | All resources; public labels are ignored |
| Non-OIDC bearer token | Public resources only |
Namespace list is always label-filtered
The namespace endpoint always enforces the opendepot.defdev.io/public=true label. System namespaces are never returned regardless of auth mode.
GroupBinding for Browse Access¶
GroupBinding resources grant OIDC-authenticated users access beyond the public set. They use an expr-lang expression against the OIDC groups claim.
apiVersion: opendepot.defdev.io/v1alpha1
kind: GroupBinding
metadata:
name: platform-team-binding
namespace: opendepot-system
spec:
expression: '"platform-team" in groups'
moduleResources:
- "terraform-aws-*"
- "terraform-gcp-vpc"
providerResources:
- "aws"
- "google"
See GroupBinding Access Control for full expression syntax, client credentials, and first-match semantics.