Introduction
The 1.15.0 release of Vault Enterprise included SAML as a new supported authentication method. This guide is intended to be viewed as a baseline for the minimum required configuration for successfully authenticating to Vault Enterprise using the SAML authentication method.
A tutorial is also available which uses Okta as the SAML IDP at https://developer.hashicorp.com/vault/tutorials/auth-methods/saml.
Expected Outcome
Successful authentication to Vault Enterprise using SAML as the authentication method.
Prerequisites
- The minimum version required for both client and server is 1.15.0.
- Vault Enterprise binaries must be used for both client and server.
- A paid license is required to use Vault Enterprise.
Procedure
Vault configuration:
$ vault read auth/saml/config
WARNING! The following warnings were returned from Vault:
* verbose_logging has been enabled. This is not recommended in production
since sensitive information may be present in SAML responses.
Key Value
--- -----
acs_urls [https://vault.nicecorp.org:8200/v1/auth/saml/callback]
default_role project-aqua-developers
entity_id https://vault.nicecorp.org:8200/v1/auth/saml/callback
idp_metadata_url https://adfs.nicecorp.org/FederationMetadata/2007-06/FederationMetadata.xml
verbose_logging true
$ vault read auth/saml/role/project-aqua-developers
Key Value
--- -----
bound_attributes map[]
bound_attributes_type string
bound_subjects [*@nicecorp.org]
bound_subjects_type glob
groups_attribute http://schemas.xmlsoap.org/claims/Group
token_bound_cidrs []
token_explicit_max_ttl 0s
token_max_ttl 0s
token_no_default_policy false
token_num_uses 0
token_period 0s
token_policies []
token_ttl 24h
token_type default
Verbose logging is enabled for debug purposes and is referenced later in this article.
AD FS Relying Party Trust configuration:
PS C:\Users\Administrator> Get-ADFSRelyingPartyTrust -Name Vault | Select-Object Name, Identifier, ProtocolProfile, MetadataUrl, IssuanceTransformRules
Name : Vault
Identifier : {https://vault.nicecorp.org:8200/v1/auth/saml/callback}
ProtocolProfile : WsFed-SAML
MetadataUrl :
IssuanceTransformRules : @RuleTemplate = "LdapClaims"
@RuleName = "UPN as Name ID"
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
=> issue(store = "Active Directory", types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"), query = ";userPrincipalName;{0}", param = c.Value);
@RuleTemplate = "LdapClaims"
@RuleName = "UPN as Email"
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
=> issue(store = "Active Directory", types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"), query = ";userPrincipalName;{0}", param = c.Value)
Additionally the Relying Party Trust has an Endpoint configured as follows:
Endpoint type: SAML Assertion Consumer
Binding: POST
Set the trusted URL as default: ticked
Index: 0
Trusted URL: https://vault.nicecorp.org:8200/v1/auth/saml/callback
Parameter matching between Vault and AD FS:
Notably, the Identifier value in the Relying Party Trust aligns with the entity_id value in the Vault SAML configuration, while the Endpoint in the Relying Party Trust aligns with the acs_urls value in the Vault SAML configuration.
Users in Active Directory have a UPN in the format of name@nicecorp.org which aligns with the bound_subjects value in the Vault role configuration.
A successful login
When authenticating using the above configuration (including verbose logging being enabled) the Vault server (active node) will write an entry to the Vault operational log at TRACE level which includes the text received SAML response: api=callback response="long-base64-string"
. When we process the string through a base64 decode it looks as follows:
SAML response (Click to expand)
<samlp:Response ID="_81dde6e0-c5a2-4a87-ae46-a27be4c064a0" Version="2.0" IssueInstant="2024-03-14T22:12:11.097Z" Destination="https://vault.nicecorp.org:8200/v1/auth/saml/callback" Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified" InResponseTo="_555fac2a-622b-5e31-0f7c-6a1d810db7c9" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"> <Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">http://adfs.nicecorp.org/adfs/services/trust</Issuer> <samlp:Status> <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/> </samlp:Status> <Assertion ID="_7782c71d-4b81-489f-948d-9616de65ec74" IssueInstant="2024-03-14T22:12:11.097Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"> <Issuer>http://adfs.nicecorp.org/adfs/services/trust</Issuer> <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> <ds:SignedInfo> <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/> <ds:Reference URI="#_7782c71d-4b81-489f-948d-9616de65ec74"> <ds:Transforms> <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> </ds:Transforms> <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> <ds:DigestValue>aVfcCHHSwJJ4aw062VX1YHte0dhARb0Uq7AtDvO5GWU=</ds:DigestValue> </ds:Reference> </ds:SignedInfo> <ds:SignatureValue>removed-for-length-reasons</ds:SignatureValue> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <X509Data> <X509Certificate>removed-for-length-reasons</X509Certificate> </X509Data> </KeyInfo> </Signature> <Subject> <NameID>niles.peppertrout@nicecorp.org</NameID> <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <SubjectConfirmationData InResponseTo="_555fac2a-622b-5e31-0f7c-6a1d810db7c9" NotOnOrAfter="2024-03-14T22:17:11.097Z" Recipient="https://vault.nicecorp.org:8200/v1/auth/saml/callback"/> </SubjectConfirmation> </Subject> <Conditions NotBefore="2024-03-14T22:12:11.097Z" NotOnOrAfter="2024-03-14T23:12:11.097Z"> <AudienceRestriction> <Audience>https://vault.nicecorp.org:8200/v1/auth/saml/callback</Audience> </AudienceRestriction> </Conditions> <AttributeStatement> <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"> <AttributeValue>niles.peppertrout@nicecorp.org</AttributeValue> </Attribute> </AttributeStatement> <AuthnStatement AuthnInstant="2024-03-14T22:12:11.019Z" SessionIndex="_7782c71d-4b81-489f-948d-9616de65ec74"> <AuthnContext> <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</AuthnContextClassRef> </AuthnContext> </AuthnStatement> </Assertion> </samlp:Response>
The most valuable pieces of the SAML response are as follows:
1. The Subject statement includes the users UPN being included as the NameID attribute, which is compared against the bound_subjects configuration parameter on the role in Vault (*@nicecorp.org):
<Subject>
<NameID>niles.peppertrout@nicecorp.org</NameID>
<SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<SubjectConfirmationData InResponseTo="_555fac2a-622b-5e31-0f7c-6a1d810db7c9" NotOnOrAfter="2024-03-14T22:17:11.097Z" Recipient="https://vault.nicecorp.org:8200/v1/auth/saml/callback"/>
</SubjectConfirmation>
</Subject>
2. The Audience statement is populated with the value which is checked against the entity_id configuration parameter in the SAML configuration within Vault (auth/saml/config > entity_id):
<Conditions NotBefore="2024-03-14T22:12:11.097Z" NotOnOrAfter="2024-03-14T23:12:11.097Z">
<AudienceRestriction>
<Audience>https://vault.nicecorp.org:8200/v1/auth/saml/callback</Audience>
</AudienceRestriction>
</Conditions>
3. The email address attribute is also required in order to build the attribute statement:
<AttributeStatement>
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress">
<AttributeValue>niles.peppertrout@nicecorp.org</AttributeValue>
</Attribute>
</AttributeStatement>
Common errors
If the IDP used for SAML with Vault is not configured correctly and the required attributes/claims are not returned by the IDP in the SAML response to Vault the authentication process will fail. The following are examples of errors observed in the Vault operational log when the necessary values are not included in the SAML response:
failed to validate SAML response: api=callback error="saml.(ServiceProvider).ParseResponse: attribute statement missing"
failed to validate SAML response: api=callback error="saml.(ServiceProvider).ParseResponse: subject missing"
Additional Information
-
Vault SAML API documentation - https://developer.hashicorp.com/vault/api-docs/auth/saml
- What is SAML? - https://www.cloudflare.com/en-au/learning/access-management/what-is-saml/