3.9. Authentication and Authorization — Apache CouchDB® 3.5 Documentation

# 3.9. Authentication and Authorization

## 3.9.1. Server Administrators

[admins]

Changed in version 3.0.0: CouchDB requires an admin account to start. If an admin account has not been created, CouchDB will print an error message and terminate.

CouchDB server administrators and passwords are not stored in the `_users` database, but in the last `[admins]` section that CouchDB finds when loading its ini files. See :config:intro for details on config file order and behaviour. This file (which could be something like `/opt/couchdb/etc/local.ini` or `/opt/couchdb/etc/local.d/10-admins.ini` when CouchDB is installed from packages) should be appropriately secured and readable only by system administrators:

    [admins]
    ;admin = mysecretpassword
    admin = -hashed-6d3c30241ba0aaa4e16c6ea99224f915687ed8cd,7f4a3e05e0cbc6f48a0035e3508eef90
    architect = -pbkdf2-43ecbd256a70a3a2f7de40d2374b6c3002918834,921a12f74df0c1052b3e562a23cd227f,10000

Administrators can be added directly to the `[admins]` section, and when CouchDB is restarted, the passwords will be salted and encrypted. You may also use the HTTP interface to create administrator accounts; this way, you don’t need to restart CouchDB, and there’s no need to temporarily store or transmit passwords in plaintext. The HTTP `/_node/{node-name}/_config/admins` endpoint supports querying, deleting or creating new admin accounts:

    GET /_node/nonode@nohost/_config/admins HTTP/1.1
    Accept: application/json
    Host: localhost:5984

    HTTP/1.1 200 OK
    Cache-Control: must-revalidate
    Content-Length: 196
    Content-Type: application/json
    Date: Fri, 30 Nov 2012 11:37:18 GMT
    Server: CouchDB (Erlang/OTP)

    {
        "admin": "-hashed-6d3c30241ba0aaa4e16c6ea99224f915687ed8cd,7f4a3e05e0cbc6f48a0035e3508eef90",
        "architect": "-pbkdf2-43ecbd256a70a3a2f7de40d2374b6c3002918834,921a12f74df0c1052b3e562a23cd227f,10000"
    }

If you already have a salted, encrypted password string (for example, from an old ini file, or from a different CouchDB server), then you can store the “raw” encrypted string, without having CouchDB doubly encrypt it.

    PUT /_node/nonode@nohost/_config/admins/architect?raw=true HTTP/1.1
    Accept: application/json
    Content-Type: application/json
    Content-Length: 89
    Host: localhost:5984

    "-pbkdf2-43ecbd256a70a3a2f7de40d2374b6c3002918834,921a12f74df0c1052b3e562a23cd227f,10000"

    HTTP/1.1 200 OK
    Cache-Control: must-revalidate
    Content-Length: 89
    Content-Type: application/json
    Date: Fri, 30 Nov 2012 11:39:18 GMT
    Server: CouchDB (Erlang/OTP)

    "-pbkdf2-43ecbd256a70a3a2f7de40d2374b6c3002918834,921a12f74df0c1052b3e562a23cd227f,10000"

Further details are available in security, including configuring the work factor for `PBKDF2`, and the algorithm itself at PBKDF2 (RFC-2898).

Changed in version 1.4: PBKDF2 server-side hashed salted password support added, now as a synchronous call for the `_config/admins` API.

## 3.9.2. Authentication Configuration

[chttpd]
  require_valid_user

    Changed in version 3.2: moved from [couch_httpd_auth] to [chttpd] section

    When this option is set to `true`, no requests are allowed from anonymous users. Everyone must be authenticated.

        [chttpd]
        require_valid_user = false

  require_valid_user_except_for_up

    When this option is set to `true`, no requests are allowed from anonymous users, except for the `/_up` endpoint. Everyone else must be authenticated.

        [chttpd]
        require_valid_user_except_for_up = false

[chttpd_auth]

  Changed in version 3.2: These options were moved to [chttpd_auth] section: authentication_redirect, timeout, auth_cache_size, allow_persistent_cookies, iterations, min_iterations, max_iterations, secret, users_db_public, x_auth_roles, x_auth_token, x_auth_username, cookie_domain, same_site.

  allow_persistent_cookies

    Changed in version 3.2: moved from [couch_httpd_auth] to [chttpd_auth] section

    When set to `true`, CouchDB will set the Max-Age and Expires attributes on the cookie, which causes user agents (like browsers) to preserve the cookie over restarts.

        [chttpd_auth]
        allow_persistent_cookies = true

  cookie_domain

    Added in version 2.1.1.

    Changed in version 3.2: moved from [couch_httpd_auth] to [chttpd_auth] section

    Configures the `domain` attribute of the `AuthSession` cookie. By default the `domain` attribute is empty, resulting in the cookie being set on CouchDB’s domain.

        [chttpd_auth]
        cookie_domain = example.com

  same_site

    Added in version 3.0.0.

    Changed in version 3.2: moved from [couch_httpd_auth] to [chttpd_auth] section

    When this option is set to a non-empty value, a `SameSite` attribute is added to the `AuthSession` cookie. Valid values are `none`, `lax` or `strict`.:

        [chttpd_auth]
        same_site = strict

  auth_cache_size

    Changed in version 3.2: moved from [couch_httpd_auth] to [chttpd_auth] section

    Number of User Context Object to cache in memory, to reduce disk lookups.

        [chttpd_auth]
        auth_cache_size = 50

  authentication_redirect

    Changed in version 3.2: moved from [couch_httpd_auth] to [chttpd_auth] section

    Specifies the location for redirection on successful authentication if a `text/html` response is accepted by the client (via an `Accept` header).

        [chttpd_auth]
        authentication_redirect = /_utils/session.html

  hash_algorithms

    Added in version 3.3.

    Note

    Until CouchDB version 3.3.1, Proxy Authentication used only the hash algorithm `sha1` as validation of `X-Auth-CouchDB-Token`.

    Sets the HMAC hash algorithm used for cookie and proxy authentication. You can provide a comma-separated list of hash algorithms. New cookie sessions or session updates are calculated with the first hash algorithm. All values in the list can be used to decode the cookie session and the token `X-Auth-CouchDB-Token` for Proxy Authentication.

        [chttpd_auth]
        hash_algorithms = sha256, sha

    Note

    You can select any hash algorithm the version of erlang used in your CouchDB install supports. The common list of available hashes might be:

        sha, sha224, sha256, sha384, sha512

    To retrieve a complete list of supported hash algorithms you can use our `bin/remsh` script and retrieve a full list of available hash algorithms with `crypto:supports(hashs).` or use the _node/{node-name}/_versions endpoint to retrieve the hashes.

    Warning

    We do not recommend using the following hash algorithms:

        md4, md5

  iterations

    Added in version 1.3.

    Changed in version 3.2: moved from [couch_httpd_auth] to [chttpd_auth] section

    The number of iterations for password hashing by the PBKDF2 algorithm. A higher number provides better hash durability, but comes at a cost in performance for each request that requires authentication. When using hundreds of thousands of iterations, use session cookies, or the performance hit will be huge. (The internal hashing algorithm is SHA1, which affects the recommended number of iterations.)

        [chttpd_auth]
        iterations = 10000

  min_iterations

    Added in version 1.6.

    Changed in version 3.2: moved from [couch_httpd_auth] to [chttpd_auth] section

    The minimum number of iterations allowed for passwords hashed by the PBKDF2 algorithm. Any user with fewer iterations is forbidden.

        [chttpd_auth]
        min_iterations = 100

  max_iterations

    Added in version 1.6.

    Changed in version 3.2: moved from [couch_httpd_auth] to [chttpd_auth] section

    The maximum number of iterations allowed for passwords hashed by the PBKDF2 algorithm. Any user with greater iterations is forbidden.

        [chttpd_auth]
        max_iterations = 100000

  password_regexp

    Added in version 3.2.

    A list of Regular Expressions to check new/changed passwords. When set, new user passwords must match all RegExp in this list.

    A RegExp can be paired with a reason text: `[{"RegExp", "reason text"}, ...]`. If a RegExp doesn’t match, its reason text will be appended to the default reason of `Password does not conform to requirements.`

        [couch_httpd_auth]
        ; Password must be 10 chars long and have one or more uppercase and
        ; lowercase char and one or more numbers.
        password_regexp = [{".{10,}", "Min length is 10 chars."}, "[A-Z]+", "[a-z]+", "\\d+"]

  proxy_use_secret

    Changed in version 3.2: moved from [couch_httpd_auth] to [chttpd_auth] section

    When this option is set to `true`, the `chttpd_auth/secret` option is required for Proxy Authentication.

        [chttpd_auth]
        proxy_use_secret = false

  public_fields

    Added in version 1.4.

    Changed in version 3.2: moved from [couch_httpd_auth] to [chttpd_auth] section

    A comma-separated list of field names in user documents (in `couchdb/users_db_suffix`) that can be read by any user. If unset or not specified, authenticated users can only retrieve their own document.

        [chttpd_auth]
        public_fields = first_name, last_name, contacts, url

    Note

    Using the `public_fields` allowlist for user document properties requires setting the `chttpd_auth/users_db_public` option to `true` (the latter option has no other purpose):

        [chttpd_auth]
        users_db_public = true

  secret

    Changed in version 3.2: moved from [couch_httpd_auth] to [chttpd_auth] section

    The secret token is used for Proxy Authentication and for Cookie Authentication.

        [chttpd_auth]
        secret = 92de07df7e7a3fe14808cef90a7cc0d91

    Note

    You can change the secret value at any time. New cookies will be signed with the new value and the previous value will be cached for the duration of the auth `timeout` parameter.

    The secret value should be set on all nodes at the same time. CouchDB will tolerate a discrepancy, however, as each node sends its secret to the other nodes of the cluster.

    The easiest rotation method is to enable the config auto-reload feature then update the secret in the `.ini` file of each node.

  timeout

    Changed in version 3.2: moved from [couch_httpd_auth] to [chttpd_auth] section

    Number of seconds since the last request before sessions will be expired.

        [chttpd_auth]
        timeout = 600

  users_db_public

    Added in version 1.4.

    Changed in version 3.2: moved from [couch_httpd_auth] to [chttpd_auth] section

    Allow all users to view user documents. By default, only admins may browse all users documents, while users may browse only their own document.

        [chttpd_auth]
        users_db_public = false

  x_auth_roles

    Changed in version 3.2: moved from [couch_httpd_auth] to [chttpd_auth] section

    The HTTP header name (`X-Auth-CouchDB-Roles` by default) that contains the list of a user’s roles, separated by a comma. Used for Proxy Authentication.

        [chttpd_auth]
        x_auth_roles = X-Auth-CouchDB-Roles

  x_auth_token

    Changed in version 3.2: moved from [couch_httpd_auth] to [chttpd_auth] section

    The HTTP header name (`X-Auth-CouchDB-Token` by default) containing the token used to authenticate the authorization. This token is an HMAC-SHA1 created from the `chttpd_auth/secret` and `chttpd_auth/x_auth_username`. The secret key should be the same on the client and the CouchDB node. This token is optional if the value of the `chttpd_auth/proxy_use_secret` option is not `true`. Used for Proxy Authentication.

        [chttpd_auth]
        x_auth_token = X-Auth-CouchDB-Token

  x_auth_username

    Changed in version 3.2: moved from [couch_httpd_auth] to [chttpd_auth] section

    The HTTP header name (`X-Auth-CouchDB-UserName` by default) containing the username. Used for Proxy Authentication.

        [chttpd_auth]
        x_auth_username = X-Auth-CouchDB-UserName

  upgrade_hash_on_auth

    Added in version 3.4.

    Changed in version 3.5.

    Upgrade user auth docs during the next successful authentication using the current password hashing settings. The default was changed from `false` to `true` in version `3.5.0`:

        [chttpd_auth]
        upgrade_hash_on_auth = true

[jwt_auth]
  required_claims

    This parameter is a comma-separated list of additional mandatory JWT claims that must be present in any presented JWT token. A 404 Not Found is sent if any are missing.

        [jwt_auth]
        required_claims = exp,iat

  roles_claim_name

    Warning

    `roles_claim_name` is deprecated in CouchDB 3.3, and will be removed later. Please migrate to `roles_claim_path`.

    If presented, it is used as the CouchDB user’s roles list as long as the JWT token is valid. The default value for `roles_claim_name` is `_couchdb.roles`.

    Note

    Values for `roles_claim_name` can only be top-level attributes in the JWT token. If `roles_claim_path` is set, then `roles_claim_name` is ignored!

    Let’s assume, we have the following configuration:

        [jwt_auth]
        roles_claim_name = my-couchdb.roles

    CouchDB will search for the attribute `my-couchdb.roles` in the JWT token.

        {
            "my-couchdb.roles": [
                "role_1",
                "role_2"
            ]
        }

  roles_claim_path

    Added in version 3.3.

    This parameter was introduced to overcome disadvantages of `roles_claim_name`, because it is not possible with `roles_claim_name` to map nested role attributes in the JWT token.

    Note

    If `roles_claim_path` is set, then `roles_claim_name` is ignored!

    Now it is possible the read a nested roles claim from JWT tokens into CouchDB. As always, there is some theory at the beginning to get things up and running. Don’t get scared now, it’s really short and easy. Honestly!

    There are only two characters with a special meaning. These are

    > - `.` for nesting json attributes and

    > - `\.` to skip nesting

    That’s it. Really.

    Let’s assume there is the following data-payload in the JWT token:

        {
            "resource_access": {
                "security.settings": {
                    "account": {
                        "roles": [
                            "manage-account",
                            "view-profile"
                        ]
                    }
                }
            }
        }

    Now, let’s define the config variable `roles_claim_path` for this example. It should look like this:

        roles_claim_path = resource_access.security\.settings.account.roles

    If an attribute has a `.` in the key like `security.settings`, you have to escape it in the config parameter with `\.`. If you use a `.` then it gets interpreted as a nested sub-key. Let’s illustrate the behavior with a second example. There is the following config parameter for `roles_claim_name` (by the way it was the default value if you didn’t configured it):

        roles_claim_name = _couchdb.roles

    Note

    CouchDB doesn’t set any default or implicit value for `roles_claim_path`.

    To migrate from `roles_claim_name` to `roles_claim_path` you need to change the parameter name and escape the `.` to prevent CouchDB to read this as a nested JSON key.

        roles_claim_path = _couchdb\.roles

    Let’s assume your JWT token have the following data-payload for your couchdb roles claim:

        {
            "_couchdb.roles": [
                "accounting-role",
                "view-role"
            ]
        }

    If you did everything right, the response from the `_session` endpoint should look something like this:

        GET /_session HTTP/1.1
        Host: localhost:5984
        Authorization: Bearer <JWT token>

        HTTP/1.1 200 OK
        Content-Type: application/json

        {
            "ok": true,
            "userCtx": {
                "name": "1234567890",
                "roles": [
                    "accounting-role",
                    "view-role"
                ]
            },
            "info": {
            "authentication_handlers": [
                "jwt",
                "proxy",
                "cookie",
                "default"
            ],
            "authenticated": "jwt"
            }
        }

    That’s all, you are done with the migration from `roles_claim_name` to `roles_claim_path` Easy, isn’t it?

[chttpd_auth_lockout]
  mode

    When set to `off`, CouchDB will not track repeated authentication failures.

    When set to `warn`, CouchDB will log a warning when repeated authentication failures occur for a specific user and client IP address.

    When set to `enforce` (the default), CouchDB will reject requests with a 403 status code if repeated authentication failures occur for a specific user and client IP address.

        [chttpd_auth_lockout]
        mode = enforce

  threshold

    When `threshold` (default `5`) number of failed authentication requests happen within the same `max_lifetime` period, CouchDB will lock out further authentication attempts for the rest of the `max_lifetime` period if `mode` is set to `enforce`.

        [chttpd_auth_lockout]
        threshold = 5

  max_objects

    The maximum number of username+IP pairs that CouchDB will track, to limit memory usage. Defaults to `10,000`. Changes to this setting are only picked up at CouchDB start or restart time.

        [chttpd_auth_lockout]
        max_objects = 10000

  max_lifetime

    The maximum duration of the lockout period, measured in milliseconds. Changes to this setting are only picked up at CouchDB start or restart time.

        [chttpd_auth_lockout]
        max_lifetime = 300000