docs/rfcs/20220208_admin_api_basic_auth.md
Enable admin API clients to authenticate using SASL username/password credientials passed into an HTTP "Basic" Authentication header.
These checks will be off by default for backward compatibility, but enabled during setup of new clusters.
A cluster configuration property:
admin_api_require_auth (boolean, default false).When this property is true, requests to the admin API will be rejected unless they
carry a valid username+password, and that username is the existing superusers list.
Currently, users' only secure option for the admin API is to enable mTLS and disable plain HTTP access, and then only issue mTLS client certs to users who are permitted to perform administrative operations.
This causes two problems:
Resolving these issues unlocks use of the Admin API in production environments, including new centralized configuration workflows that rely on admin API access.
The existing superusers configuration property will be used to discriminate between
regular users, and users that should be permitted to use the admin API.
The plaintext password in the Authentication header can be validated against stored scram credentials, by passing the password through the same salt/hmac steps that we would use if setting a new password.
--user and --password on rpk.rpk cluster config edit)In extreme circumstances, they can disable auth using
rpk cluster config force-reset admin_api_require_auth while Redpanda is offline.
However, unless the user forgets a password they should not be able to lock themselves out: the API endpoint for modifying cluster config will ensure that when auth is enabled, it is always enabled by an authenticated user who is already a superuser, so that a naive user can't permanently lock themselves out just by enabling auth before they've declared themselves a superuser.
All the concepts in use here already exist:
We are using seastar's built-in HTTP framework, which does not provide generic request/response hooks: there is not a place to connect an authentication callback.
As a substitute, we will introduce a helper wrapper around our method callbacks, that applies authentication rules before running the inner function.
To support dynamic updates to superusers and admin_api_require_sasl, the
values of these properties will simply not be cached anywhere. Reading them
out of the per-shard cluster configuration object at the start of each request
is a cheap operation.
All endpoints will be be subject to authentication rules, with two exceptions:
/v1/metrics - the metrics are not generally sensitive, and it is very
convenient to be able to point prometheus at an endpoint without having
to arrange secrets/v1/status - a node should be willing to tell any client whether it is up.All rpk commands that rely on admin API access will now require proper
--user and --password flags on systems where admin_require_sasl is true.
The kubernetes operator currently relies on unauthenticated access to the admin API. It also creates and stores superuser credentials when creating a cluster, so extending it to use these credentials to access the API is straightforward, as long as the end user does not themselves modify these superuser credentials.
During kubernetes cluster creation, the operator can bootstrap authentication as follows:
admin_api_require_sasl to true.Clearly the above sequence is simplified if the cluster does not have any external connectivity to the admin API.
SCRAM credentials may be either sha256 or sha512 type, whereas Authentication header does not specify which to use. For existing systems, we can only validate passwords by trying both algorithms.
The credential store should be extended to record the algorithm for each credential. This
might be done as part of implementing this feature, or we might choose to defer that until
the serde transition, for convenient backward compatible encoding.
rpk.sh wrapper that automatically loads superuser credentials from
kubernetes.This is not possible using existing stored SCRAM credentials, because HTTP digest hashing is different from the hashing used in SCRAM credentials.
We could implement this for newly created credentials if we calculated and stored the HTTP Digest MD5 hash of the password during account creation (at which time, we have the plaintext password).
While HTTP digest auth is slightly better than basic auth in that it doesn't transmit passwords in the clear, it has many security issues of its own, and in practice either of these protocols should be transported over TLS for a meaningful level of security.
If the admin API only listened on 127.0.0.1, then users could SSH to a redpanda node and drive admin operations from there. This has several downsides:
It is convenient but not essential to use the same system of credentials for the admin API that we use for Kafka protocol. We could implement a separate pool of API keys.
This approach would increase the surface area of the feature substantially, as we would not be able to use the existing user CRUD commands, and would be more complex to explain to the user compared with the existing user/password framework they know from the world of Kafka.
For use cases like the kubernetes operator, it might be sufficient to simply store a random string in the node configuration file (redpanda.yaml), and use this as a shared secret.
This has several downsides:
For some use cases (e.g. monitoring), it might be convenient to give the user read-only access without providing a secret.
However, this cannot be applied uniformly to all endpoints, for example the config endpoint includes sensitive configuration properties like the cloud access key. It would also remove the ability to record an audit record of which users were accessing what information.
This isn't so much an alternative as a possible extension. The authorization layer can be extended in many ways in the future: this RFC is just about getting some kind of authentication (SASL user account) combined with the most basic level of authorization (the superuser list).
Integration with operator, if enable admin API auth in the cloud is needed. Currently admin API is not exposed to users on FMC clusters.