Login MFA
OpenBao supports Multi-factor Authentication (MFA) for authenticating to an auth method using different authentication types. Login MFA is built on top of the Identity system of OpenBao.
MFA types
MFA in OpenBao includes the following login types:
-
Time-based One-time Password (TOTP)
- If configured and enabled on a login path, this would require a TOTP passcode along with an OpenBao token to be presented while invoking the API login request. The passcode will be validated against the TOTP key present in the caller's identify in OpenBao. -
Okta
- If Okta push is configured and enabled on a login path, then the enrolled device of the user will receive a push notification to either approve or deny access to the API. The Okta username will be derived from the caller identity's alias. -
Duo
- If Duo push is configured and enabled on a login path, then the enrolled device of the user will receive a push notification to either approve or deny access to the API. The Duo username will be derived from the caller identity's alias. Note that Duo could also be configured to use passcodes for authentication. -
PingID
- If PingID push is configured and enabled on a login path, the enrolled device of the user will receive a push notification to either approve or deny access to the API. The PingID username will be derived from the caller identity's alias.
Login MFA procedure
NOTE: OpenBao's built-in Login MFA feature does not protect against brute forcing of
TOTP passcodes by default. We recommend that per-client rate limits
are applied to the relevant login and/or mfa paths (e.g. /sys/mfa/validate
). External MFA
methods (Duo
, Ping
and Okta
) may already provide configurable rate limiting. Rate limiting of
Login MFA paths are enforced by default.
Login MFA can be configured to secure further authenticating to an auth method. To enable login MFA, an MFA method needs to be configured. Please see Login MFA API for details on how to configure an MFA method. Once an MFA method is configured, an operator can configure an MFA enforcement using the returned unique MFA method ID. Please see Login MFA Enforcement API for details on how to configure an MFA enforcement config. MFA could be enforced for an entity, a group of entities, a specific auth method accessor, or an auth method type. A login request that matches any MFA enforcement restrictions is subject to further MFA validation, such as a one-time passcode, before being authenticated.
There are two ways to validate a login request that is subject to MFA validation.
Single-Phase login
In the Single-phase login, the required MFA information is embedded in a login request using
the X-Vault-MFA
header. In this case, the MFA validation is done
as a part of the login request.
MFA credentials are retrieved from the X-Vault-MFA
HTTP header. The format of
the header is either mfa_method_id[:passcode]
or
mfa_method_id[:passcode=<passcode>]
, and one can use either of the above two
formats. The item in the []
is optional. If there are multiple MFA methods
that need to be validated, a user can pass in multiple X-Vault-MFA
HTTP
headers.
Sample request
$ curl \
--header "X-Vault-Token: ..." \
--header "X-Vault-MFA: d16fd3c2-50de-0b9b-eed3-0301dadeca10:695452" \
http://127.0.0.1:8200/v1/auth/userpass/login/alice
If an MFA method does not require a passcode, the login request MFA header only contains the method ID.
$ curl \
--header "X-Vault-Token: ..." \
--header "X-Vault-MFA: d16fd3c2-50de-0b9b-eed3-0301dadeca10" \
http://127.0.0.1:8200/v1/auth/userpass/login/alice
An operator can configure a name for an MFA method. This name should be unique in the namespace in which the MFA method is configured. The MFA method name can be used in the MFA header.
$ curl \
--header "X-Vault-Token: ..." \
--header "X-Vault-MFA: sample_mfa_method_name:695452" \
http://127.0.0.1:8200/v1/auth/userpass/login/alice
In cases where the MFA method is configured in a specific namespace, the MFA method name should be prefixed with the namespace path.
Below shows an example where an MFA method is configured in ns1
.
$ curl \
--header "X-Vault-Token: ..." \
--header "X-Vault-MFA: ns1/sample_mfa_method_name:695452" \
http://127.0.0.1:8200/v1/auth/userpass/login/alice
Two-Phase login
The more conventional and prevalent MFA method is a two-request mechanism, also referred to as Two-phase Login MFA.
In Two-phase login, the X-Vault-MFA
header is not provided in the request. In this case, after sending a regular login request,
the user receives an auth response in which MFA requirements are included. MFA requirements contain an MFA request ID
which identifies the login request that needs validation. In addition, MFA requirements contain MFA constraints
that determine which MFA types should be used to validate the request, the corresponding method IDs, and
a boolean value showing whether the MFA method uses passcodes or not. MFA constraints form a nested map in MFA Requirement
and represent all MFA enforcements that match a login request. While the example below is for the userpass login,
note that this can affect the login response on any auth mount protected by MFA validation.
Sample Two-Phase login response
{
"request_id": "1044c151-13ea-1cf5-f6ed-000c42efd477",
"lease_id": "",
"lease_duration": 0,
"renewable": false,
"data": null,
"warnings": [
"A login request was issued that is subject to MFA validation. Please make sure to validate the login by sending another request to mfa/validate endpoint."
],
"auth": {
"client_token": "",
"accessor": "",
"policies": null,
"token_policies": null,
"identity_policies": null,
"metadata": null,
"orphan": false,
"entity_id": "",
"lease_duration": 0,
"renewable": false,
"mfa_requirement": {
"mfa_request_id": "d0c9eec7-6921-8cc0-be62-202b289ef163",
"mfa_constraints": {
"enforcementConfigUserpass": {
"any": [
{
"type": "totp",
"id": "820997b3-110e-c251-7e8b-ff4aa428a6e1",
"uses_passcode": true,
"name": "sample_mfa_method_name",
}
]
}
}
}
}
}
Note that the uses_passcode
boolean value will always show true for TOTP, and false for Okta and PingID.
For Duo method, the value can be configured as part of the method configuration, using the use_passcode
parameter.
Please see Duo API for details
on how to configure the boolean value for Duo.
To validate the MFA restricted login request, the user sends a second request to the validate endpoint including the MFA request ID and MFA payload. MFA payload contains a map of methodIDs and their associated credentials. If the configured MFA methods, such as PingID, Okta, and Duo, do not require a passcode, the associated credentials will be a list with one empty string.
Sample payload
{
"mfa_request_id": "5879c74a-1418-1948-7be9-97b209d693a7",
"mfa_payload": {
"d16fd3c2-50de-0b9b-eed3-0301dadeca10": ["910201"]
}
}
If an MFA method is configured in a namespace, the MFA method name prefixed with the namespace path can be used in the validation payload.
{
"mfa_request_id": "5879c74a-1418-1948-7be9-97b209d693a7",
"mfa_payload": {
"ns1/sample_mfa_method_name": ["910201"]
}
}
Sample request
$ curl \
--header "X-Vault-Token: ..." \
--request POST \
--data @payload.json \
http://127.0.0.1:8200/v1/sys/mfa/validate
Sample CLI request
A user is also able to use the CLI write command to validate the login request.
$ bao write sys/mfa/validate -format=json @payload.json
Interactive CLI for login MFA
OpenBao supports an interactive way of authenticating to an auth method using CLI only if the
login request is subject to a single MFA method validation. In this situation, if the MFA method
is configured to use passcodes, after sending a regular login request, the user is prompted to
insert the passcode. Upon successful MFA validation, a client token is returned.
If the configured MFA methods, such as PingID, Okta, and Duo, do not require a passcode and have out of band
mechanisms for verifying the extra factor, the user is notified to check their authenticator application.
This alleviates a user from sending the second request separately to validate a login request.
To disable the interactive login experience, a user needs to pass in the non-interactive
flag to the login request.
$ bao write -non-interactive sys/mfa/validate -format=json @payload.json
TOTP passcode validation rate limit
Rate limiting of Login MFA paths are enforced by default. OpenBao allows for 5
consecutive failed TOTP passcode validations. This value can also be configured
by adding max_validation_attempts
to the TOTP configuration. If the number of
consecutive failed TOTP passcode validation exceeds the configured value, the
user needs to wait until a fresh TOTP passcode is available.