Home / Alt manpages / docker-secret-inspect(1)

  • docker-secret-inspect(1)
  • User command
  • linux

Inspect Docker Swarm Secrets Without Exposing Their Contents

docker secret inspect reads only metadata, but names, labels and timestamps can still say more about your deployment than you meant to share. This covers reading that metadata for one or more secrets, pulling a single field with a Go template, and recognising the errors that mean you are on the wrong node or typed the wrong name. About ten minutes if you already have manager access.

This guide describes Docker CLI 29.8.1, provided here by docker-ce-cli 5:29.8.1-1~ubuntu.24.04~noble. The command's shape is stable enough to be useful elsewhere, but check exact fields against your own installed help on other releases.

1. Check the installed command

Start with read-only checks. Neither changes Docker state, and neither normally needs sudo:

$ command -v docker
/usr/bin/docker
$ docker --version
Docker version 29.8.1, build 4a63305
$ docker secret inspect --help
Usage:  docker secret inspect [OPTIONS] SECRET [SECRET...]

Display detailed information on one or more secrets

A secret can be identified by name or ID. This is a Docker Swarm command, not ordinary standalone-container administration, which matters before you spend time debugging what looks like a wrong name.

2. Confirm the client reaches a Swarm manager

Inspecting a Swarm secret is a cluster-management operation. Run:

$ docker info --format '{{.Swarm.LocalNodeState}} {{.Swarm.ControlAvailable}}'
active true

Expect active true on a manager. Wording can differ across Docker versions and contexts, but the facts that matter are that Swarm is active and this node has manager control. If Docker says this node is not a manager, switch context rather than run docker swarm init, which changes cluster state and belongs to a different guide entirely.

Checkpoint

Confirm the target context before inspecting anything sensitive:

$ docker context show
default
$ docker info --format 'server={{.ServerVersion}} swarm={{.Swarm.LocalNodeState}} manager={{.Swarm.ControlAvailable}}'
server=29.8.1 swarm=active manager=true

Your context name and server version will differ. If the context points at a production manager, treat every name, label and timestamp you get back as production information.

3. Inspect one secret by name or ID

Use a real name from your approved inventory. Listing is also read-only:

$ docker secret ls
ID                          NAME              DRIVER    CREATED         UPDATED
eo7jnzguqgtpdah3cm5srfb97   app-config        <none>    3 minutes ago   3 minutes ago
$ SECRET_NAME='app-config'
$ docker secret inspect "$SECRET_NAME"
[
  {
    "ID": "eo7jnzguqgtpdah3cm5srfb97",
    "Version": { "Index": 17 },
    "CreatedAt": "2017-03-24T08:15:09.735271783Z",
    "UpdatedAt": "2017-03-24T08:15:09.735271783Z",
    "Spec": {
      "Name": "app-config",
      "Labels": { "env": "dev" }
    }
  }
]

Those timestamps, the ID and the version are examples of shape, not values to expect on your own host. The CLI renders results as a JSON array by default, even for one object: identity, version, timestamps, name and labels. There is no command for reading the payload, so do not try to substitute a host file path or a container environment variable for the secret name.

4. Select one field for scripts

Use --format or -f when a script needs one value rather than the whole document. Docker runs the supplied Go template against each match:

$ docker secret inspect --format '{{.Spec.Name}}' "$SECRET_NAME"
app-config
$ docker secret inspect --format '{{.CreatedAt}}' "$SECRET_NAME"
2017-03-24 08:15:09.735271783 +0000 UTC

That timestamp is illustrative; yours will hold whatever the manager actually stored. Keep the template quoted so the shell passes braces and spaces through unchanged. Need several fields? Emit one deliberately simple, machine-readable line and handle escaping in the consuming program rather than parsing the human-facing JSON with a chain of fragile text filters.

The special value json asks Docker to print JSON for each result:

$ docker secret inspect --format json "$SECRET_NAME"
{"ID":"eo7jnzguqgtpdah3cm5srfb97","Version":{"Index":17},"CreatedAt":"2017-03-24T08:15:09.735271783Z","UpdatedAt":"2017-03-24T08:15:09.735271783Z","Spec":{"Name":"app-config","Labels":{"env":"dev"}}}

Tip

--pretty gives a friendlier display during an incident. It is still metadata, not content, and less suited to a script.

5. Inspect several secrets carefully

Pass multiple names or IDs after the options:

$ docker secret inspect --format '{{.Spec.Name}} {{.UpdatedAt}}' app-config api-token
app-config 2017-03-24 08:15:09.735271783 +0000 UTC
api-token 2017-03-24 08:16:11.735271783 +0000 UTC

A missing name fails the whole command, so partial output is not proof every requested secret was found. For an automated check, capture the exit status and count returned records against requested identifiers. Avoid broad output capture in shared terminals and CI logs: names and labels can disclose deployment structure even with the payload staying protected.

6. Diagnose the common failures

None of these change state:

$ docker secret inspect definitely-not-a-real-secret
Error response from daemon: secret definitely-not-a-real-secret not found
$ printf 'exit status: %s\n' "$?"
exit status: 1
  • Not found: exact wording varies by release, but a non-zero status means check the spelling, the current context, and whether the object actually exists in this Swarm. A secret from another cluster will not appear just because the name looks familiar.
  • Not a manager: switch to an approved manager context. Do not run docker swarm init on a host already in another environment.
  • Access denied: ask for the narrowly scoped manager permission you actually need. Do not join a broad administrative group just to inspect one secret.
  • Daemon unreachable: fix the Docker context or service access first. Changing the secret is not a connectivity test.

Done means

  • Checked the command and Docker CLI version locally.
  • Confirmed the active context reaches a Swarm manager, or recorded the manager-context blocker.
  • Identified the requested secret by an approved name or ID.
  • Chose default JSON, a selected field, or --pretty for the actual reader.
  • Kept the secret payload out of every command, transcript and log.
  • Checked the exit status, especially when inspecting several secrets at once.