Skip to main content
Version: Development

etcd database secrets engine

etcd is one of the supported plugins for the database secrets engine. This plugin generates dynamic credentials against an etcd cluster's built-in v3 Auth API, using the official etcd Go client. It also supports Static Roles.

See the database secrets engine docs for more information about setting up the database secrets engine.

creation_statements is a JSON role document rather than a semicolon-separated list of statements. It can list pre-existing etcd role names under roles, define inline roles and key permissions under custom_roles, or combine both. Roles listed under roles must already exist on the cluster. Roles under custom_roles are created by the plugin if necessary before they are granted to the new user.

Capabilities​

Plugin NameRoot Credential RotationDynamic RolesStatic RolesUsername Customization
etcd-database-pluginYesYesYesYes

Setup​

  1. Enable the database secrets engine if it is not already enabled:

    $ bao secrets enable database
    Success! Enabled the database secrets engine at: database/

    By default, the secrets engine will enable at the name of the engine. To enable the secrets engine at a different path, use the -path argument.

  2. Configure OpenBao with the proper plugin and connection information. The root credentials only need to be provided if authentication is enabled on the cluster:

    $ bao write database/config/etcd \
    plugin_name="etcd-database-plugin" \
    allowed_roles="reader" \
    endpoints="https://etcd.example.com:2379" \
    username="root" \
    password="password"
    Success! Data written to: database/config/etcd
  3. Configure a role that maps a name in OpenBao to an etcd role-grant document. This example grants a pre-existing etcd role, so reader must already exist on the cluster:

    $ bao write database/roles/reader \
    db_name="etcd" \
    creation_statements='{"roles":["reader"]}' \
    default_ttl="1h" \
    max_ttl="24h"
    Success! Data written to: database/roles/reader

    Alternatively, define a custom role and its permissions inline:

    $ bao write database/roles/app-writer \
    db_name="etcd" \
    creation_statements='{"custom_roles":[{"name":"app_writer","permissions":[{"permission":"readwrite","key":"/app/","prefix":true}]}]}' \
    default_ttl="1h" \
    max_ttl="24h"
    Success! Data written to: database/roles/app-writer

Usage​

After the secrets engine is configured and a user/machine has an OpenBao token with the proper permission, it can generate credentials.

  1. Generate a new credential by reading from the /creds endpoint with the name of the role:

    $ bao read database/creds/reader
    Key Value
    --- -----
    lease_id database/creds/reader/2f6a614c-4aa2-7b19-24b9-ad944a8d4de6
    lease_duration 1h
    lease_renewable true
    password SsnoaA-8Tv4t34f41baD
    username v-token-reader-x7g2kf8s1a2b-1717000000

etcd-specific notes​

  • No native credential expiry: etcd has no expiry concept on users, so lease expiry for dynamic roles is enforced purely by OpenBao revoking the lease (UserDelete), not by the database itself.
  • Partial-failure cleanup: UserAdd is not transactional with the subsequent UserGrantRole calls. If any role grant fails (for example, the role does not exist), the plugin deletes the just-created user before returning the error, so no half-configured user is left behind.
  • Custom-role lifecycle: roles defined under custom_roles are created if necessary and are preserved when a dynamic user is revoked, because other active users may still reference them. Custom-role management is additive-only: permissions omitted from a later role definition are not revoked, and changing a key or range does not remove the old range. To narrow access, revoke obsolete permissions directly in etcd or use a new, uniquely named role and retire the old role after its active credentials are revoked. Do not share custom-role names across OpenBao roles unless permission accumulation is intentional.
  • Idempotent revocation: deleting a user that no longer exists is treated as success, so lease revocation is safe to retry.
  • endpoints accepts a comma-separated list: point it at every member you want the client to be able to reach, e.g. https://etcd1:2379,https://etcd2:2379,https://etcd3:2379.

API​

The full list of configurable options can be seen in the etcd database plugin API page.

For more information on the database secrets engine's HTTP API please see the Database secrets engine API page.