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

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

List Docker Swarm Secrets Without Exposing Their Values

A Swarm with two dozen secrets and a vague name to find is exactly when docker secret ls earns its place. This covers safely listing secret metadata, narrowing it by name or label, and producing script-friendly output, all without printing a single secret's contents. About ten minutes, needing Docker Engine access to a Swarm manager and the docker-ce-cli package. Checked here against Docker 29.8.1, package version 5:29.8.1-1~ubuntu.24.04~noble.

This command lists metadata only. It never shows a secret's stored value, and it never creates, updates or removes one. Keep that boundary in mind anyway: a name, label or creation time can still reveal operational detail worth protecting.

1. Check the installed command

Confirm which client is running and read the local command contract. Ordinary, read-only, and normally needs no elevated privileges:

$ docker --version
Docker version 29.8.1, build 4a63305
$ docker secret ls --help
Usage:  docker secret ls [OPTIONS]

List secrets

Three options are documented: --filter to narrow results, --format for custom output, and --quiet for IDs only. This is a Docker Swarm command, not ordinary standalone-container administration.

Checkpoint

If docker --version reports a different release, trust the local help and manual page as the authority for that host's syntax.

2. Confirm the client can reach a Swarm manager

Run the basic listing from the Docker context you intend to inspect:

$ docker secret ls
ID                          NAME        CREATED        UPDATED
<secret-id>                 <secret-name>  <relative-time>  <relative-time>

That shows the shape of a result, not literal values to paste. A real list can be empty, and exact columns or time wording can vary by release. On a worker, or a host not in the Swarm at all, expect something like:

Error response from daemon: This node is not a swarm manager.

That is a placement problem, not a reason to run docker swarm init on a production host just to make a read-only command work. Switch to the approved manager or context instead. If the daemon itself refuses your account, ask the host administrator for access; adding yourself to the Docker group is a security decision outside this guide.

Checkpoint

Continue only once the command reaches the intended manager. If the list comes back empty, record that rather than assume a filter is hiding something.

3. Filter by a known name or ID

Filter when the manager holds more secrets than you need. Quote the whole key=value expression so the shell treats it as one argument:

$ docker secret ls --filter "name=payments"
ID                          NAME             CREATED        UPDATED
<matching-id>               payments-config  <relative-time>  <relative-time>

The documented name filter matches a full name or a prefix; an ID filter accepts a full ID or a prefix too:

$ docker secret ls --filter "id=<secret-id-prefix>"
  • Use a value from your own listing. Never guess an ID, and never put a secret value into a filter.
  • Repeat the flag for more than one condition: docker secret ls --filter "name=payments" --filter "label=environment=production".
  • Label filters take two forms: a key alone, such as label=environment, or a key and value together.
$ docker secret ls --filter "name=payments" --filter "label=environment=production"

Filtering only changes what is displayed. It never touches the secret or its labels.

4. Select output for a person or a script

For a quick inventory, --quiet prints IDs only:

$ docker secret ls --quiet
<secret-id-1>
<secret-id-2>

Useful as input to a later, reviewed command, but an ID is still an identifier for sensitive infrastructure: do not feed it straight into a destructive command without checking the target first.

For stable field selection, use a Go template. Docker documents .ID, .Name, .CreatedAt, .UpdatedAt and .Labels:

$ docker secret ls --format '{{.ID}}\t{{.Name}}\t{{.CreatedAt}}'
<secret-id>    <secret-name>    <relative-time>

Single quotes stop the shell interpreting the braces. For JSON lines, use the documented json directive:

$ docker secret ls --format json
{"CreatedAt":"<relative-time>","Driver":"","ID":"<secret-id>","Labels":"","Name":"<secret-name>","UpdatedAt":"<relative-time>"}

Treat this as metadata JSON, not a way to retrieve a secret's value. If another tool consumes it, check that tool's error handling and avoid writing the output to a broadly readable temp file.

5. Diagnose an empty or unexpected result

Rerun the unfiltered command against the same context first:

$ docker secret ls
$ docker context show

If that is empty too, check you are on the expected manager and context, and that what you are searching for is actually a Swarm secret rather than an environment variable, a bind-mounted file, or another Docker resource entirely. Both name and ID filters are prefix-based, so a short or ambiguous prefix can return more than one row. If a template produces blank fields, check the placeholder spelling against the installed documentation, and keep a plain table listing on hand so you can tell a formatting mistake from a genuinely missing object. Do not reach for sudo as a reflex: it can select a different configuration or context and put you on the wrong daemon entirely.

6. Keep the inspection reversible

Every command here is read-only. There is no undo step because listing, filtering and formatting never change Swarm state. The commands that create, rotate or remove secrets are separate operations and are deliberately not covered here.

Warning

Never paste a secret value into a terminal transcript, ticket, shell history, filter, label or diagnostic bundle. If one gets exposed anyway, follow your organisation's incident and rotation procedure; listing the metadata will not rotate it for you.

Done means

  • Verified the Docker client version and the local docker secret ls syntax.
  • Confirmed the selected context reaches the intended Swarm manager.
  • Listed metadata without attempting to print any secret value.
  • Filtered by a known name, ID or label, understanding prefix matching.
  • Chose IDs, a Go template or JSON metadata for the next read-only step.
  • Changed nothing: no Swarm initialised, no secret, service or privilege touched.