Logging into a private registry with Podman isn’t just about giving it credentials; it’s about Podman learning to trust a specific, potentially self-signed, identity for pulling images.

Let’s see it in action. Imagine you have a private registry at myregistry.local:5000 and you need to pull an image named my-app:latest.

First, you’d try to pull it without logging in, and it would likely fail with an authentication error.

podman pull myregistry.local:5000/my-app:latest
# Error:  manifest unknown: manifest unknown

This error means the registry said "Who are you?" and Podman didn’t have a good answer. To fix this, you need to authenticate. The primary command for this is podman login.

podman login myregistry.local:5000
Username: myuser
Password: mypassword
Login Succeeded!

Now, if you try the pull again:

podman pull myregistry.local:5000/my-app:latest
# Getting image source signatures
# Copying blob sha256:abcdef1234567890...
# Copying blob sha256:...
# Copying manifest sha256:...
# Storing signatures
# myregistry.local:5000/my-app:latest: ...

Success. Podman now has a valid token for myregistry.local:5000 and can authenticate subsequent requests.

The core problem Podman registry authentication solves is securing access to container images. Without it, anyone could pull your proprietary application images. The podman login command facilitates this by obtaining an authentication token from the registry. This token is then included in subsequent HTTP requests to the registry API, allowing the registry to verify your identity and grant access to the requested image layers and manifests.

Internally, podman login communicates with the registry’s authentication endpoint. For registries implementing the Docker Registry HTTP API V2, this typically involves a GET /v2/ request. If authentication is required, the registry responds with a 401 Unauthorized status and a WWW-Authenticate header. This header tells Podman how to authenticate (e.g., Basic realm="Registry" or Bearer realm="https://myregistry.local:5000/v2/",service="registry",scope="registry:pull:*") and what parameters are needed. Podman then uses the provided username and password (or other credentials) to construct the appropriate Authorization header for subsequent requests.

Once authenticated, Podman stores these credentials or, more commonly, the resulting authentication token in a configuration file, usually located at ~/.config/containers/auth.json. This file is JSON formatted and contains entries like:

{
  "auths": {
    "myregistry.local:5000": {
      "auth": "bXl1c2VyOm15cGFzc3dvcmQ=" // Base64 encoded "myuser:mypassword"
    }
  },
  "credsStore": "default"
}

The auth field is a Base64 encoded string of username:password. Podman uses this stored information for subsequent podman pull, podman push, and podman run operations that target myregistry.local:5000, avoiding the need to re-enter credentials each time.

A common point of confusion is when you’re using a registry that uses a different authentication method, like a token-based authentication service separate from the registry itself. In such cases, podman login might require additional parameters, or you might need to pre-fetch a token and provide it via a credential helper. The auth.json file can also store more complex authentication details beyond simple username/password, including refresh tokens or specific token endpoints.

If you’re working with a self-signed certificate for your private registry, you’ll also need to configure Podman to trust that certificate. This is typically done by placing the CA certificate (or the registry’s certificate itself if it’s acting as its own CA) into the system’s or Podman’s certificate trust store. For Podman specifically, you can often place the certificate file (e.g., myregistry.local.crt) in /etc/containers/certs.d/myregistry.local:5000/ and ensure it’s readable by the Podman daemon or user. Without this, even a successful login might result in TLS handshake errors when Podman tries to communicate with the registry.

The next hurdle you’ll likely encounter is dealing with image signing and verification, ensuring the images you pull are not only from the correct registry but also unaltered and from a trusted source.

Want structured learning?

Take the full Podman course →