OpenKeel: the sovereign French Cloud solution of the inherent group, with a European reach Discover inherent

Reverse-spec · Clients

python-barbicanclient — Scenarios

End-to-end scenarios — python-barbicanclient — branch stable/2026.2

Branch stable/2026.2 @ 8162006e8677 — repository https://opendev.org/openstack/python-barbicanclient — analysed on 2026-11-01

The client's sequences were [observed] on the local stub. The service's part (what Barbican does and answers) was read in barbican: or is not known; a stub only answers what it is told, so these diagrams prove nothing about a real service.

1. Any command: startup and negotiation

sequenceDiagram
  autonumber
  actor U as Operator
  participant C as openstack + barbicanclient
  participant K as Keystone
  participant B as Barbican
  U->>C: openstack secret list
  C->>K: GET /identity (discovery)
  C->>K: POST /identity/v3/auth/tokens
  K-->>C: 201, X-Subject-Token, catalog
  C->>B: GET <catalog URL> (no token, no version header)
  B-->>C: 300 {"versions":{"values":[{status:"stable",...}]}}
  C->>B: GET <catalog URL>/v1  OpenStack-API-Version: key-manager 1.1
  alt normal
    B-->>C: 200 {"version":{status:"CURRENT",min_version:"1.0",max_version:"1.2"}}
    Note over C: picks 1.2
  else status stable
    B-->>C: 200 {"version":{status:"stable"}}
    Note over C: picks 1.0, consumer commands refused
  else 406
    B-->>C: 406
    Note over C: no bounds, picks 1.2 anyway
  else no max_version, or range below 1.0
    B-->>C: 200
    C-->>U: "Invalid client version v1", must be one of v1 (exit 1)
  end
  C->>B: GET /v1/secrets?limit=10&offset=0  OpenStack-API-Version: key-manager 1.2

Sources: barbicanclient/v1/client.py:89, barbicanclient/v1/client.py:125, barbicanclient/client.py:215. Service: barbican:barbican/api/controllers/versions.py:156.

Diagnostics: Invalid client version v1 is not about the version given: it hides a version document without max_version or a range problem. Run with --debug and read the answer of GET …/v1. Could not find requested endpoint in Service Catalog. with a healthy catalog means discovery returned an empty list [observed]. Failed to contact the endpoint … for discovery followed by Unrecognized schema in response body. (HTTP 404) means the version URLs answer 404 [observed].

2. Store a secret, then read it back

sequenceDiagram
  autonumber
  actor U as Operator
  participant C as openstack + barbicanclient
  participant B as Barbican
  U->>C: secret store --name n --payload p
  Note over C: payload encoded to bytes, then base64
  C->>B: POST /v1/secrets/ {name, algorithm, mode, bit_length, secret_type, payload:"cA==", content type octet-stream, encoding base64}
  alt 201 with secret_ref
    B-->>C: {"secret_ref": ".../secrets/U"}
    C-->>U: table with href, Status None, Created None
  else 201 with empty body
    B-->>C: empty
    C-->>U: Expecting value: line 1 column 1 (char 0), exit 1, the secret may exist
  end
  U->>C: secret get --payload .../secrets/U
  C->>B: GET /v1/secrets/U/payload  Accept: text/plain
  alt 200 valid UTF-8
    B-->>C: p
    C-->>U: table with Payload
  else 200 not UTF-8
    B-->>C: bytes
    C-->>U: Secret does not contain a payload, Payload None, exit 0
  else 406
    B-->>C: {"title":"Not Acceptable",...}
    C-->>U: Not Acceptable: ..., exit 1
  end

Sources: barbicanclient/barbican_cli/v1/secrets.py:190, barbicanclient/v1/secrets.py:338, barbicanclient/v1/secrets.py:312. The 406 branch follows the service code (barbican:barbican/plugin/util/translations.py:103), and the not-UTF-8 branch is what the client does if the service sends that.

Diagnostics: a secret shown as application/octet-stream while text was given is the normal result of --payload without -t. Do not read Status None as a failure: the secret was stored; rerun secret get.

3. Generate a key through an order

sequenceDiagram
  autonumber
  actor U as Operator
  participant C as openstack + barbicanclient
  participant B as Barbican
  participant W as Barbican worker
  U->>C: secret order create key --name n
  C->>B: POST /v1/orders/ {"type":"key","meta":{name,algorithm,bit_length,payload_content_type,mode}}
  B-->>C: 202 {"order_ref": ".../orders/O"}
  C-->>U: Order href, Status None
  B-)W: order processing (service side)
  loop the user polls, the client has no --wait
    U->>C: secret order get .../orders/O
    C->>B: GET /v1/orders/O
    B-->>C: {type, meta, status, secret_ref...}
    C-->>U: Status PENDING, ACTIVE or ERROR
  end
  U->>C: secret get <Secret href>

Sources: barbicanclient/v1/orders.py:200, barbicanclient/v1/orders.py:343. Service status 202: barbican:barbican/api/controllers/orders.py:205. The worker part is in the Barbican reverse-spec.

Diagnostics: Invalid KeyOrder meta field: […], Unknown Order type "None" and … got an unexpected keyword argument come from the client reading the order, not from the service [observed]. One order of an unknown type stops the whole secret order list [observed]. asymmetric without --algorithm asks for aes, 256 [observed]; expect the service to refuse or fail it [inferred].

4. Add a user to an ACL (read-modify-write)

sequenceDiagram
  autonumber
  actor U as Operator
  participant C as openstack + barbicanclient
  participant B as Barbican
  U->>C: acl user add .../secrets/U --user u1
  Note over C: URI must hold "secrets" or "containers", and no "/acl"
  C->>B: GET /v1/secrets/U/acl
  B-->>C: {"read":{"project-access":true,"users":["u0"],...}}
  Note over C: users extended, no dedupe
  C->>B: PUT /v1/secrets/U/acl {"read":{"project-access":true,"users":["u0","u1"]}}
  alt JSON answer
    B-->>C: {"acl_ref":"..."}
    C->>B: GET /v1/secrets/U/acl
    C-->>U: table
  else empty body
    B-->>C: empty
    C-->>U: Expecting value: ..., exit 1, the change may be applied
  end

Sources: barbicanclient/barbican_cli/v1/acls.py:170, barbicanclient/v1/acls.py:292, barbicanclient/v1/acls.py:341.

Diagnostics: Secret or container URI is not specified. means a bare UUID was given, and Secret ACL URI provided. Expecting Secret URI. means the URL holds /acl, possibly in the host name [observed]. ACL data for secret is not provided. on user remove means the GET returned an empty object, which the service does not do: it answers a default read ACL (barbican:barbican/api/controllers/acls.py:200).

5. Delete a secret with consumers

sequenceDiagram
  autonumber
  actor U as Operator
  participant C as openstack + barbicanclient
  participant B as Barbican
  U->>C: secret delete .../secrets/U [--force]
  alt microversion 1.2
    C->>B: DELETE /v1/secrets/U[?force=1]
    alt no consumers, or force
      B-->>C: 204
      C-->>U: exit 0
    else consumers, no force
      B-->>C: 400 {"title":..., "description":"Secret cannot be deleted as it has consumers."}
      Note over C: text compared with SecretHasConsumers
      C-->>U: Secret cannot be deleted as it has consumers. (exit 1)
    end
  else below 1.2
    C->>B: GET /v1/secrets/U
    B-->>C: secret, with consumers
    alt no consumers, or --force
      C->>B: DELETE /v1/secrets/U
      Note over C: no force parameter
    else consumers
      C-->>U: Secret cannot be deleted as it has consumers. (exit 1, client side)
    end
  end

Sources: barbicanclient/v1/secrets.py:582, barbicanclient/v1/secrets.py:600, barbicanclient/v1/secrets.py:610. Service: barbican:barbican/api/controllers/secrets.py:258, status of the exception barbican:barbican/common/exception.py:174.

Diagnostics: at 1.2 the detection depends on the exact English text in the error (barbicanclient/v1/secrets.py:606). A different wording gives a plain HTTPClientError, still exit 1.

6. Legacy shell without authentication

sequenceDiagram
  autonumber
  actor U as Operator
  participant L as barbican shell
  participant B as Barbican
  U->>L: barbican --no-auth --endpoint http://h/key-manager --os-project-id p secret list
  Note over L: deprecation warning on stderr
  L->>B: GET http://h/key-manager  OpenStack-API-Version: key-manager 1.1
  B-->>L: 300 {"versions":[{status:"CURRENT",min_version,max_version}]}
  L->>B: GET http://h/key-manager/v1/secrets?limit=10&offset=0  X-Project-Id: p
  B-->>L: 200
  L-->>U: table

Sources: barbicanclient/barbican.py:177, barbicanclient/client.py:39, barbicanclient/client.py:51.

Diagnostics: messages appear 3 times, because logging.basicConfig and two calls to configure_logging each add a handler (barbicanclient/barbican.py:381, barbicanclient/barbican.py:349) [observed]. It depends on the service accepting X-Project-Id without a token, i.e. a deployment without keystonemiddleware [inferred].

Source: reverse-spec-python-barbicanclient/04-scenarios_stable-2026.2.md. The _rewrite/ and _inventory/ files are not published on the site.