Create the dictionary
Use the data from your business requirements and authorization use cases to define relevant attributes in an attribute dictionary document. A well-structured attribute dictionary enhances communication among stakeholders, including internal teams, PIP owners, and auditors.
| Namespace and name | Category | Type | Source | Key | Responsible/SLA | Cardinality | Reference | Description | Examples |
|---|---|---|---|---|---|---|---|---|---|
acme.user.identity | subject | string | PEP | - | - | 1..1 | HR AD, 6 character alphanum | Acme employee signature | johsmi, jandoe |
acme.customer.identity | resource | string | PEP | - | - | 0...* | Salesforce customer id | Customer(s) involved in action | 231698, 249111 |
acme.customer.location | resource | string | Salesforce customer PIP | acme.customer.identity | Business Operation team, 99% | 0...* | ISO 3166-1 | Customer origin country | SE, US |
id is a reserved word in ALFA and can not be used in attribute names. For a full list of reserved words, see the Attribute identifiersOpens in a new tabsection of the Access Decision Service (ADS) documentation.
Define the attributes
Before using attributes in ALFA policies or attribute connectors, you should first define them in the dictionary.
src/authorizationDomain/attributes.yaml
First, you are encouraged to delete the pre-populated attributes that came with the APD distribution.
Because APD brings together three logical entities (ADS (YAML), policies (ALFA), and tests (Java)) there are three corresponding dictionaries. You should treat the attributes.yaml file as the authoritative dictionary and generate the other two from it. See the Authoritative source: YAML or ALFA? section below for details.
Workflow:
Add attributes in
src/authorizationDomain/attributes.yamlGenerate the ALFA and Java dictionaries by running:
./gradlew generateAlfaDictionaryFromYaml generateJavaDictionaryFromYamlAlternatively, you can run these tasks from your IDE's Gradle tool window under the
Axiomatics-dictionarysection.The generated dictionary files will be located at
src/authorizationDomain/alfaSpecifications/attributes.alfaandsrc/test/java/apd/Dictionary.java. These should be committed to your repository as normal files.
If you are using Authorization Hub, you can also create the dictionary within the platform and pull it by utilizing the Authorization Hub integration. See Integrations and CI/CD for details.
To use an attribute in an ALFA policy, JUnit test or attribute connector, define it in an attributes.yaml file, then generate ALFA and JAVA dictionary. Organize your attributes into hierarchical namespaces as needed.
acme.user.role:
xacmlId: acme.user.role
category: AccessSubject
datatype: string
acme.user.location:
xacmlId: acme.user.location
category: AccessSubject
datatype: string
acme.resource.location:
xacmlId: acme.resource.location
category: Resource
datatype: string
- For the attributes above,
acme.userandacme.resourceare namespaces androle, location, locationare names. - For convenience,
xacmlIdshould be set to the same as the attribute name (first-level yaml key). categorycan beAccessSubject,Resource,ActionorEnvironmentand it specifies whether the attribute is a property of a subject (for example, role), resource (for example, owner), etc. See Choosing a category below for guidance.datatypeshould be one of the JSON shorthand type codes listed in section3.3.1 Supported Data TypesOpens in a new tab of the JSON Profile of XACML 3.0 Version 1.0 specification.- This file uses the YAML format.
Choosing a category
The category tells ADS how to group and match attributes in an authorization request. Choosing the right category is important because an attribute sent under the wrong category will not match the corresponding policy condition.
Use the following decision rule:
| Ask yourself | Category |
|---|---|
| Who is performing the action? (user, service, system) | AccessSubject |
| What is being accessed? (document, record, endpoint, file) | Resource |
| What action is being performed? (read, write, approve, delete) | Action |
| What is independent of all parties? (current time, date, day of week) | Environment |
Examples:
| Attribute | Category | Reason |
|---|---|---|
user.role | AccessSubject | It is a property of the user making the request |
user.location | AccessSubject | It is a property of the user: where they are located |
user.ip_address | AccessSubject | It is a property of the requesting client |
user.risk_score | AccessSubject | It is a computed property of the user's session or identity |
resource.classification | Resource | It is a property of the thing being accessed |
resource.owner | Resource | It describes ownership of the accessed item |
action.name | Action | It describes what operation is being requested |
environment.time | Environment | It is independent of any subject, resource, or action |
environment.date | Environment | It is a calendar property of the request moment |
When in doubt, AccessSubject and Resource cover the vast majority of real-world ABAC attributes. Environment is reserved for attributes that are truly independent of all parties (typically time and date). Action is used when policy decisions depend on what operation is being performed, not just who or what.
ADS provides three standard XACML environment attributes automatically on every authorization request which you do not need to define them in attributes.yaml:
| XACML attribute ID | ALFA name | Type |
|---|---|---|
urn:oasis:names:tc:xacml:1.0:environment:current-time | currentTime | time |
urn:oasis:names:tc:xacml:1.0:environment:current-date | currentDate | date |
urn:oasis:names:tc:xacml:1.0:environment:current-dateTime | currentDateTime | dateTime |
You can use these directly in ALFA policies and in JUnit tests with .with("urn:oasis:names:tc:xacml:1.0:environment:current-time", "09:00:00").
It is strongly recommended to have name and xacmlId set to the same value, solely to minimize the risk of typos and mistakes. If you already have policies in production following the XACML standard of having attribute ids as URNs, there is a chance your attribute ids contain the : character. This character is not valid in the YAML dictionary. In such case, leave xacmlId to your orginal attribute ID and chose a new attribute name. Then, you must also disable the APD check that validates names and ids are equal:
alfa {
extraAttributeIdCheck false
}
Authoritative source: YAML or ALFA?
APD maintains three synchronized representations of your attribute dictionary:
| File | Format | Used by |
|---|---|---|
src/authorizationDomain/attributes.yaml | YAML | ADS (directly loaded into the domain) |
src/authorizationDomain/alfaSpecifications/attributes.alfa | ALFA | ALFA policy compiler |
src/test/java/apd/Dictionary.java | Java | JUnit tests |
Use attributes.yaml as the authoritative source. Generate the other two from it using generateAlfaDictionaryFromYaml and generateJavaDictionaryFromYaml. This is the recommended workflow because:
- YAML is the format ADS reads natively. Keeping it as the source of truth means no translation step before deployment.
- Adding an attribute in YAML and regenerating is simpler than editing ALFA, which requires knowing the ALFA namespace block syntax.
- The
generateYamlDictionaryFromAlfatask (the reverse direction) exists for one purpose: migrating projects that started with ALFA-first development, or recovering the YAML file after it has been lost. It is not intended for ongoing use.
If you use Authorization Hub, you can pull the attribute dictionary from Authorization Hub using DictionaryPullFrom{environment}. This rewrites attributes.yaml and then regenerates both the ALFA and Java dictionaries automatically. YAML remains authoritative even in this case.