Docker Engine 29.8.0: --umask Flag, Custom AppArmor Profiles, and CloudWatch Entity Logging

Docker Engine 29.8.0: --umask Flag, Custom AppArmor Profiles, and CloudWatch Entity Logging

Docker Engine 29.8.0 shipped on September 3, 2026, and it's a release worth actually reading the changelog for instead of skimming past. It doesn't add a headline feature โ€” it closes four small, specific gaps that practitioners have been working around with entrypoint scripts, custom AppArmor policies deployed by hand, or CloudWatch dashboards missing service context. If you run containers with strict file-permission requirements, manage your own AppArmor policy, ship logs to CloudWatch, or run anything on top of Docker's VMM/Hyper-V backend, at least one of these changes affects you directly.

Why this release matters more than a typical patch bump

Docker's engine releases in 2026 have leaned hard into host-isolation hardening after a run of container-escape CVEs earlier in the year (CopyEscape in docker cp being the most recent, patched in 29.7.0). 29.8.0 continues that pattern โ€” two of its four changes are security hardening, not new features โ€” while also picking up two long-requested operational conveniences: setting a container's umask without an entrypoint wrapper, and getting real service identity into CloudWatch logs. None of these require an application rebuild; they're all daemon or CLI-level changes.

What's actually in 29.8.0

1. The --umask flag for docker create / docker run

Before 29.8.0, if you needed every file a container's process created to land with a non-default permission mask, you had two bad options: bake a umask 027 call into your entrypoint script, or override the entrypoint entirely just to set it. Neither survives someone else's base image cleanly.

Docker 29.8.0 adds a first-class flag:

1docker run --umask 027 my-image

This sets the umask for the container's main process, and โ€” this is the part worth noting โ€” for docker exec sessions and healthchecks run against that container too, not just PID 1. That matters if your healthcheck script writes a status file or lock file; before this release it could silently inherit a different umask than the process it's checking.

Set it at daemon level via daemon.json if you want a fleet-wide default instead of per-container flags:

1{
2  "default-umask": "027"
3}

(Per-container --umask still overrides the daemon default when both are set.)

2. Daemon-level custom AppArmor profile templates

Teams running hardened Docker hosts have historically had two options for AppArmor: use Docker's built-in docker-default profile, or manage a completely separate profile per container with --security-opt apparmor=<profile>. There was no supported way to modify the template Docker itself generates the default profile from.

29.8.0 adds daemon support for exactly that. Set it via daemon.json:

1{
2  "apparmor-profile": "/etc/docker/apparmor/docker-default.tpl"
3}

or the equivalent daemon flag:

1dockerd --apparmor-profile=/etc/docker/apparmor/docker-default.tpl

Don't set both โ€” Docker treats that as a configuration error. Store the template file outside /etc/apparmor.d/ (Docker's docs specifically call this out) so the host's AppArmor service doesn't try to parse it as a live profile before Docker has finished templating it.

Your custom template has to preserve four Go text/template substitutions Docker fills in at container-start time: .Abi, .Name, .Imports, and .InnerImports (plus .DaemonProfile if you're adding rules for daemon-signal handling). Drop any of those and container start will fail with an AppArmor profile load error, not a helpful "you forgot a template variable" message โ€” so start from a copy of the stock docker-default template and diff your changes against it rather than writing one from scratch.

After restarting the daemon:

1sudo systemctl restart docker
2docker info --format '{{json .SecurityOptions}}'

Confirm your template path shows up in the AppArmor entry before assuming it took effect.

3. CloudWatch entity attributes for the awslogs driver

This is the one most teams running CloudWatch Container Insights or Application Signals will actually feel. The awslogs logging driver previously shipped raw log events with no structured "which service produced this" metadata beyond whatever you encoded into the log stream name. 29.8.0 adds three new --log-opt keys that attach real CloudWatch entity metadata to every log event:

1docker run --log-driver awslogs \
2  --log-opt awslogs-region=us-east-1 \
3  --log-opt awslogs-group=my-log-group \
4  --log-opt awslogs-entity-service-name=checkout-api \
5  --log-opt awslogs-entity-environment=production \
6  --log-opt awslogs-entity-attributes="version=2.4.1,team=payments" \
7  my-image
  • awslogs-entity-service-name and awslogs-entity-environment both support the same Go-template placeholders awslogs-stream already supports ({{.Name}}, {{.ID}}), so you can derive them from the container instead of hardcoding.
  • They're an all-or-nothing pair. Setting only one and not the other is a validation error at container start, not a silent partial config โ€” Docker requires both because CloudWatch's entity model needs both to identify a service.
  • awslogs-entity-attributes takes free-form key=value pairs (up to 10) for anything else you want attached โ€” version, team, region, whatever your Application Signals dashboards key on.
  • The entity type Docker sends is fixed to Service. If CloudWatch rejects the entity metadata for any reason (bad IAM permissions, malformed attribute), it degrades to a warning โ€” your log events still land, you just lose the entity linkage, so check for awslogs warnings in the daemon log rather than assuming missing dashboard data means missing logs.

4. AF_VSOCK / socketcall hardening

The quieter security change: Docker now blocks containers from using the 32-bit socketcall(2) syscall path to open AF_VSOCK sockets, via new AppArmor and SELinux policy rules. AF_VSOCK is the socket family used for host-to-guest-VM communication (relevant to Docker's VMM backend and Hyper-V isolation). A container reaching this through the legacy 32-bit syscall multiplexer was a path around intended VM-boundary controls โ€” not a CVE with a public advisory as of this writing, but a hardening fix in the same family as the AF_ALG blocking Docker shipped in 29.4.2. Most workloads won't notice this at all; it only matters if something in your stack is deliberately opening VSOCK sockets from inside a container, which is rare outside custom VM-tooling or nested-virtualization setups.

Best practices

  • Set --umask explicitly on any container where you've historically compensated with a custom entrypoint โ€” you can likely delete that entrypoint logic now.
  • Roll out a custom AppArmor template on one host first and confirm docker info shows it before pushing to a fleet via config management โ€” a bad template blocks every container from starting on that host.
  • Add awslogs-entity-service-name and awslogs-entity-environment to your standard docker run/Compose/task-definition logging config across services now, while you're already touching logging config, rather than retrofitting service-by-service later.
  • If you're on Docker Desktop rather than a Linux Engine host, note that AppArmor customization and the AF_VSOCK hardening are Linux-host-relevant; check Desktop's own release notes for what applies to your platform.

Common mistakes to avoid

  • Setting only one of awslogs-entity-service-name / awslogs-entity-environment. This fails container startup, not just entity linkage โ€” test your logging config in staging before it's the thing blocking a production deploy.
  • Writing a custom AppArmor template from scratch instead of starting from Docker's stock docker-default template. Missing a required template variable produces an AppArmor load failure, and the error message won't tell you which variable is missing.
  • Storing the AppArmor template inside /etc/apparmor.d/. The host's AppArmor tooling can pick it up prematurely before Docker finishes templating it โ€” keep it in a separate path like /etc/docker/apparmor/.
  • Assuming --umask on docker run also covers docker exec sessions from a different Docker CLI context (e.g., a remote exec via the API with its own explicit umask override) โ€” the flag sets the container-level default, but an explicit override elsewhere still wins.

Troubleshooting

Container won't start after setting a custom AppArmor profile. Check journalctl -u docker for an AppArmor profile load error immediately after the failed start โ€” it almost always means a required template variable (.Abi, .Name, .Imports, .InnerImports) was dropped from your custom template. Diff against the stock template to find what's missing.

awslogs logs stop appearing after adding entity options. Confirm you set both awslogs-entity-service-name and awslogs-entity-environment โ€” a container that fails this validation won't start at all, so "logs stopped" here usually means "container stopped."

Entity metadata isn't showing up in CloudWatch even though the container is running fine. Check the Docker daemon log for awslogs warnings โ€” CloudWatch treats bad entity metadata (malformed attributes, insufficient IAM permissions for entity association) as a non-fatal warning, so your log events keep flowing but silently lose the service linkage.

--umask doesn't seem to affect a healthcheck's output file permissions. Confirm you're actually on Engine 29.8.0 (docker version --format '{{.Server.Version}}') โ€” the healthcheck/exec umask inheritance is new in this release specifically, not in earlier 29.x versions.

FAQ

Do I need to upgrade Docker Desktop separately to get these features? Yes โ€” Engine and Desktop version independently. Check Docker Desktop's own release notes for which bundled Engine version it ships; the umask flag and awslogs options are CLI/Engine features, while the AppArmor and AF_VSOCK changes are Linux-host daemon features that don't apply the same way inside Desktop's VM.

Does the umask flag work with Docker Compose? Yes, via the umask key at the service level in your Compose file, which maps to the same HostConfig.Umask field.

Is the AF_VSOCK hardening going to break anything for typical web-app containers? No. It only affects containers deliberately opening VSOCK sockets, which almost no application containers do. It's relevant mainly to custom VM-tooling or nested-virtualization workloads running on Docker's VMM/Hyper-V backend.

Can I use the new CloudWatch entity attributes with ECS or EKS, not just plain docker run? The --log-opt keys map directly to the awslogs log driver configuration in an ECS task definition's logConfiguration.options block. For EKS, it depends on your node's container runtime logging setup โ€” this is an Engine/CLI-level awslogs driver feature, not a Kubernetes-native one, so it only applies if your nodes are actually using Docker's awslogs driver rather than a Fluent Bit/CloudWatch agent sidecar.

Where can I see the full 29.8.0 changelog? Docker Engine version 29 release notes โ€” 29.8.0 is dated September 3, 2026 and lists all changes referenced here plus unrelated bug fixes.

Key takeaways

ChangeWhat it doesWho needs it
--umask flagSets umask for main process, execs, and healthchecksAnyone currently faking this with a custom entrypoint
Custom AppArmor profile templateDaemon-level override of the docker-default profile templateHardened hosts managing their own security policy
awslogs entity attributesAttaches Service/Environment/custom attributes to CloudWatch log eventsTeams using CloudWatch Container Insights / Application Signals
AF_VSOCK/socketcall hardeningBlocks 32-bit syscall path for VM-host socket communicationVMM/Hyper-V or nested-virtualization workloads (most others: no action needed)
ReleasedSeptember 3, 2026Check with docker version --format '{{.Server.Version}}'

Further Reading