DockLogDockLogBlog
6 min readDockLog

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:

PatternMatches
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:

text
^prod-.*-app$

Handy when prod-* would be too broad and catch prod-debug-shell you forgot about.

What does NOT work

MistakeResult
prod_* when containers use hyphensEmpty list
Production/* on Linux K8sCase-sensitive namespace mismatch
Regex without ^ or $Treated as wildcard, not regex
Empty field on non-adminUser 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:

Userallowed_containerscan_restartcan_delete
alicealice-*yesno
bobbob-*yesno
you (admin)*yesno

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 namespace
  • production/api-*, pod name prefix inside production
  • *-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.

yaml
environment:
  - RUNTIME_MODE=kubernetes
  - K8S_NAMESPACES=default,staging,production

Two layers on K8s

LayerControls
Cluster RBAC (ServiceAccount or kubeconfig)What DockLog can list at all
K8S_NAMESPACES envNamespace ceiling on the instance
Per-user allowed_containersWhat 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:

  1. Server env: ALLOW_RESTART=true (etc.)
  2. User checkbox: can_restart in 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.

ActionServer envUser flag
RestartALLOW_RESTARTcan_restart
StopALLOW_STOPcan_stop
StartALLOW_STARTcan_start
DeleteALLOW_DELETEcan_delete
ShellALLOW_SHELLcan_shell

Shell is break-glass territory. Most teams leave ALLOW_SHELL unset entirely.

Compose example (actions enabled, delete off)

yaml
environment:
  ALLOW_RESTART: "true"
  ALLOW_STOP: "true"
  # ALLOW_DELETE not set
  # ALLOW_SHELL not set

Then 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.

LoginScopeActions
acme-clientacme-*, 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

  1. Deploy with auth, DB_PATH, CLIENT_ACCESS=strict (compose post).
  2. Set server ALLOW_* gates before creating users.
  3. Create user, set allowed_containers, leave action checkboxes off.
  4. Log in as that user in a private window. Confirm container list.
  5. Enable one action flag, confirm buttons appear only for allowed scope.
  6. 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

SituationRecommendation
Solo homelab, trusted LANAuth on, * for yourself, skip per-user patterns
Shared VPS, multiple devsPrefix containers by user, pattern per user
Client access on shared metalStrict patterns, no shell, audit on
K8s staging onlyK8S_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.

Continue reading