DockLog RBAC: patterns that actually work
allowed_containers syntax for Docker and Kubernetes, plus the two-layer action model, with setups we've used on shared hosts.
Shared VPS problem: everyone can docker ps, everyone sees everyone's containers. DockLog can't fix Docker's lack of per-user views by itself, but the allowed_containers field on each user (Admin → Users) controls what shows up in the UI and API.
This is separate from Kubernetes RBAC or docker group membership. Narrow the instance's kubeconfig or socket access first where you can, then narrow again per human in DockLog.
Pattern syntax
One field, comma-separated. User sees anything matching any listed pattern.
Exact name: redis matches only redis.
Wildcards, the usual stuff:
| Pattern | Matches |
|---|---|
backend-* | backend-api, backend-worker |
*redis* | anything with redis in the name |
staging/* | every pod in namespace staging |
staging/api-* | pods starting with api- in staging |
prod-api-*,prod-worker-* | two explicit prefixes, comma-separated |
Regex: if the pattern has ^ or $, it's treated as raw regex:
^prod-.*-app$Handy when prod-* would be too broad and catch prod-debug-shell you forgot about.
What does NOT work
| Mistake | Result |
|---|---|
prod_* when containers use hyphens | Empty list |
Production/* on Linux K8s | Case-sensitive namespace mismatch |
Regex without ^ or $ | Treated as wildcard, not regex |
| Empty field on non-admin | User sees nothing |
Test with a throwaway user before giving a client their login.
Docker: shared dev box
Three developers, one host, containers prefixed by username:
| User | allowed_containers | can_restart | can_delete |
|---|---|---|---|
| alice | alice-* | yes | no |
| bob | bob-* | yes | no |
| you (admin) | * | yes | no |
Server-side: set ALLOW_RESTART=true, leave ALLOW_DELETE off unless you really want delete buttons in the UI at all.
Prod and staging on one machine
Messier. Staging folks might get staging-* and *-staging. On-call gets prod-api-*, prod-worker-*, prod-redis: explicit names, not prod-* if you have one-off containers that shouldn't be in scope.
Example one-off: prod-migration-2026-06 running a batch job. If on-call has prod-*, they see it. If they have explicit prefixes only, they don't. Pick intentionally.
Kubernetes: namespaces and pods
With RUNTIME_MODE=kubernetes or both, the same field understands namespaces.
staging, whole namespaceproduction/api-*, pod name prefix insideproduction*-cron-*, pod name pattern across namespaces the instance can see
K8S_NAMESPACES on the DockLog container is a hard ceiling, comma-separated list of namespaces the instance will even query. A user pattern of kube-system/* does nothing if kube-system isn't in that list.
environment:
- RUNTIME_MODE=kubernetes
- K8S_NAMESPACES=default,staging,productionTwo layers on K8s
| Layer | Controls |
|---|---|
| Cluster RBAC (ServiceAccount or kubeconfig) | What DockLog can list at all |
K8S_NAMESPACES env | Namespace ceiling on the instance |
Per-user allowed_containers | What each login sees |
A read-only ServiceAccount plus tight K8S_NAMESPACES plus per-user patterns is the production-shaped stack. Details in K8s log tailing.
Restart/stop/delete: two switches, not one
This trips people up constantly. A user needs both:
- Server env:
ALLOW_RESTART=true(etc.) - User checkbox:
can_restartin Admin
Admins included. If restart shouldn't exist for anyone, don't set ALLOW_RESTART at all. Greyed-out buttons mean the server gate is off, not RBAC.
| Action | Server env | User flag |
|---|---|---|
| Restart | ALLOW_RESTART | can_restart |
| Stop | ALLOW_STOP | can_stop |
| Start | ALLOW_START | can_start |
| Delete | ALLOW_DELETE | can_delete |
| Shell | ALLOW_SHELL | can_shell |
Shell is break-glass territory. Most teams leave ALLOW_SHELL unset entirely.
Compose example (actions enabled, delete off)
environment:
ALLOW_RESTART: "true"
ALLOW_STOP: "true"
# ALLOW_DELETE not set
# ALLOW_SHELL not setThen per user in Admin → Users: tick only what they need.
Agency setup (real pattern)
Client containers named acme-web, acme-worker. Client login gets acme-* and acme_* (people name things inconsistently). Your team gets * with restart allowed, delete disabled globally via ALLOW_DELETE unset.
| Login | Scope | Actions |
|---|---|---|
| acme-client | acme-*, acme_* | view logs only |
| your-dev | * | restart, no delete |
| acme-oncall (optional) | acme-* | restart during incidents |
Audit log (when DB_PATH is set) records who restarted what. Clients ask for this more than you'd expect.
Onboarding checklist
- Deploy with auth,
DB_PATH,CLIENT_ACCESS=strict(compose post). - Set server
ALLOW_*gates before creating users. - Create user, set
allowed_containers, leave action checkboxes off. - Log in as that user in a private window. Confirm container list.
- Enable one action flag, confirm buttons appear only for allowed scope.
- Add blocked-action alerts on a low-traffic channel.
Audit log
When auth and DB_PATH are enabled, DockLog records logins, restarts, stops, deletes, shell sessions, and admin edits in SQLite.
Shared dev login defeats the point. One human, one user row.
Back up docklog.db with your compose data directory. RBAC and audit live there.
Things that go wrong
"Buttons are greyed out": user has can_restart but ALLOW_RESTART isn't set on the container.
Empty pod list: patterns look right, check K8S_NAMESPACES and that the kubeconfig actually reaches that cluster.
Regex typo: test with a throwaway user before giving access to a client.
User sees too much: * or overly broad prod-*. Narrow patterns, not just action flags.
User sees too little: typo in pattern, or container renamed outside the prefix convention.
403 on API: CLIENT_ACCESS=strict expects the browser client. Custom scripts need the documented header; see reverse proxy post.
K8s works for admin, empty for client: client pattern uses Docker-style names on K8s pods. Use namespace/pod-prefix syntax.
RBAC and alerts together
Scope alert rules the same way you scope users. On-call user with prod-api-* should match alert rules on prod-api-*, not *.
K8s event alerts on production/* plus user scoped to production/api-* means they see alerts for pods they can't see in the UI. Align scopes.
When to use DockLog RBAC vs nothing
| Situation | Recommendation |
|---|---|
| Solo homelab, trusted LAN | Auth on, * for yourself, skip per-user patterns |
| Shared VPS, multiple devs | Prefix containers by user, pattern per user |
| Client access on shared metal | Strict patterns, no shell, audit on |
| K8s staging only | K8S_NAMESPACES=staging, users get staging/* |
More detail in the official RBAC guide. For alerts when someone hits a blocked action, see notifications setup. Put the instance behind HTTPS before sharing logins: production hardening.