Zero Trust and Generation of Claims
Overview
In a Zero Trust model, each access request must be continuously validated against up-to-date user directory information, even in Single Sign-On (SSO) environments. This approach ensures that each authentication attempt relies on real-time data, preventing access with outdated or revoked credentials. Rather than assuming trust based on network location or past sessions, Zero Trust revalidates user access dynamically, ensuring only authenticated, authorized users gain access.
PhenixID Authentication Services (PAS) enables this Zero Trust framework by utilizing the SequenceAuthenticator as the initial authentication step. This authenticator sequence ensures that each component in the chain is executed sequentially, with logic at the end of the flow retrieving the latest information on the user’s status. This setup enables real-time revocation of SSO access if the user’s account has been disabled or updated, reinforcing Zero Trust principles by actively validating each session.
In this setup, a DynamicAuthenticator operates as a non-interactive authenticator running a claims-generation pipe for each authentication attempt. This ensures that the latest claims are generated and that SSO validity is verified at every access request.
Authentication Flow
This flowchart illustrates a Zero Trust authentication flow using PhenixID Authentication Services (PAS):
flowchart LR
A[login request] -->|OIDC/SAML| B{SequenceAuthenticator}
B -->| | C[AuthSelector]
C --> D[OneTouch] & E[BankID] --> F[DynamicClaims]
F --> | | G{SequenceAuthenticator}
G --> | | H[Build SAML/OIDC response]
B --> | SSO | F
B-. Zero Trust Sequence .-> G
Where DynamicClaims is a DynamicAuthenticator that operates solely by running a pipe without requiring any user input. This authenticator executes with every authentication attempt, ensuring that the most up-to-date claims are generated and that SSO validity is continuously verified.
Example Configuration in PAS
This setup assumes you’ve configured an AuthSelector with several login methods. You can find more information on configuring an AuthSelector here.
Create a DynamicAuthenticator for Claims
First, create a DynamicAuthenticator that only runs a pipe, as shown in this example:
{
"id": "DynamicClaims",
"alias": "DynamicClaims",
"name": "DynamicAuthenticator"
"configuration": {
"localizationKey": "defaultAuthenticator",
"pipeID": "claims-pipe"
}
}
For more details on DynamicAuthenticator, refer here.
Example Configuration for claims-pipe
The claims-pipe handles attribute retrieval for user claims:
{
"id": "claims-pipe",
"description": "Pipe creating claims",
"enabled": "true",
"valves": [{
"name": "LDAPSearchValve",
"enabled": "true",
"config": {
"connection_ref": "<your connection_ref>",
"base_dn": [
"DC=example,DC=com"
],
"scope": "SUB",
"size_limit": "0",
"filter_template": "(&(sAMAccountName={{item.sAMAccountName}})(|(userAccountControl=512)(userAccountControl=544)(userAccountControl=66048)(userAccountControl=66080)(userAccountControl=262656)(userAccountControl=262688)(userAccountControl=328192)(userAccountControl=328224)))",
"attributes": "givenName,sn,userAccountControl",
"escape": "all"
}
},{
"name": "FlowFailValve",
"config": {
"message":"account disabled",
"exec_if_expr":"flow.firstItem().containsProperty('userAccountControl')"
}
},{
"name": "PropertyAddValve",
"config": {
"name":"name",
"value":"{{item.givenName}} {{item.sn}}",
"splitter" : ";"
}
}]
}
The filter_template
is designed to verify if a user account is active by matching the sAMAccountName
with the specified username collected during the initial authentication. It also checks that the account’s userAccountControl attribute is set to an "enabled" state, ensuring the account is active.
Capturing Immutable Attribute
To get this to work you must collect sAMAccountName in the first authentication and only that attribute. In a real environment, it should be an immutable attribute preferably instead, for example objectGUID in Active Directory.
Example LDAPSearchValve in BankID Authenticator:
{
"name": "LDAPSearchValve",
"enabled": "true",
"config": {
"connection_ref": "<your connection_ref>",
"base_dn": [
"DC=example,DC=com"
],
"scope": "SUB",
"size_limit": "0",
"filter_template": "(&(serialNumber={{request.username}})(|(userAccountControl=512)(userAccountControl=544)(userAccountControl=66048)(userAccountControl=66080)(userAccountControl=262656)(userAccountControl=262688)(userAccountControl=328192)(userAccountControl=328224)))",
"attributes": "sAMAccountName",
"escape": "all"
}
}
It is important that we always collect the immutable attribute on all authenticators included in the flow.
Create a SequenceAuthenticator
Next we need to add a SequenceAuthenticator keep the flow together. Here is a example how that authenticator could be configured:
{
"id": "zerotrustseq",
"alias": "zerotrustseq",
"name": "SequenceAuthenticator",
"configuration": {
"authenticators": [
"AuthSelector",
"DynamicClaims"
],
"localizationKey": "defaultAuthenticator"
}
}
More details on SequenceAuthenticator are available here.
Enable SSO in the AuthSelector
To enable SSO the AuthSelector must have the config parameter "setSSOParameters": "true"
Example config:
{
"id": "AuthSelector",
"alias": "AuthSelector",
"name": "AgnosticAuthSelector",
"configuration": {
"possibleAuthenticators": [
"OneTouch",
"BankID"
],
"setSSOParameters": "true"
}
}
Note that it is important that all methods have the same Level of assurance if SSO is to be enabled.
Set zerotrustseq as entrypoint
Next set zerotrustseq as entry point for the authentication on your SAML IdP or OIDC OP.
Mor information can be found here:
Verification
Here are some verification steps to ensure that the Zero Trust authentication setup with claims generation in PhenixID Authentication Services (PAS) functions as expected:
Test Initial Authentication Flow:
- Access a protected resource that initiates an authentication request via OIDC or SAML.
- Verify that the SequenceAuthenticator triggers the AuthSelector, which presents login options (e.g., OneTouch, BankID).
- Ensure the selected authenticator prompts for the expected user input (e.g., OTP for OneTouch or BankID verification).
Validate Claims Generation:
- Complete the authentication using the chosen method.
- Confirm that the DynamicClaims authenticator executes, retrieving up-to-date user attributes from the directory.
- Use a tool (like a SAML tracer or logging) to verify that claims generated in the claims-pipe match the latest directory information.
Check Real-time SSO Validation:
- While logged in, disable the user account in the directory.
- Attempt to re-access the protected resource. Ensure the DynamicClaims authenticator re-evaluates the account status, preventing access due to the account being disabled.
Completing these verification steps will confirm that each component in the flow operates as intended, enforcing Zero Trust by continuously validating each session against current user information.