Setup OCI Proxy with DevGuard Dependency Proxy

Container images are dependencies too: a single FROM line or an image reference in a Kubernetes manifest pulls code from a public registry into your builds and clusters. Typosquatted and compromised images on public registries are a recurring attack vector. The DevGuard dependency proxy sits between your container tooling and the upstream registries, checks every image against the malicious package database and enforces your firewall rules before an image reaches your machine.

Configuration

The proxy implements the OCI Distribution API, so every standard client (Docker, Podman, containerd, crane, skopeo) can pull through it. Prefix the fully qualified image reference with your DevGuard host:

The registry must be part of the reference — docker.io/library/nginx, not just nginx. The following upstream registries are supported:

RegistryExample reference
Docker Hub<your-devguard-host>/docker.io/library/alpine:3.20
GitHub Container Registry<your-devguard-host>/ghcr.io/org/image:tag
Quay<your-devguard-host>/quay.io/org/image:tag
Google Container Registry<your-devguard-host>/gcr.io/project/image:tag
Kubernetes<your-devguard-host>/registry.k8s.io/pause:3.10
Amazon ECR Public<your-devguard-host>/public.ecr.aws/org/image:tag
Microsoft Container Registry<your-devguard-host>/mcr.microsoft.com/dotnet/runtime:8.0
GitLab Container Registry<your-devguard-host>/registry.gitlab.com/group/project:tag

To apply the firewall rules of a repository, use its proxy secret as the first path segment:

Testing

DevGuard ships a test image, docker.io/fake-org/malicious-image, flagged as malicious at version v1.0.0. A tag that cannot be parsed as a version at all (such as latest below) is rejected outright, since the proxy cannot rule out that it resolves to the flagged version. The following script uses crane to pull a legitimate image through the proxy and to verify that the malicious one is rejected. --insecure is only needed for a DevGuard instance without HTTPS, e.g. a local test setup:

If the pull succeeds and the malicious image is blocked, the proxy is working correctly.

Tags are compared as versions the same way Go module versions are: 1.0.0 and v1.0.0 are equivalent spellings of the same version, so a tag does not need to match the flagged spelling exactly to be rejected:

Further Reading

Have feedback? We want to hear from you!

Fields marked with * are required