Policies
Use these endpoints to manage the ALFA policies of a project. Policies are organized in a policy package, and each policy is an ALFA file with a name and its contents. For a walkthrough, read Manage policy packages using the API.
All requests require the X-Project-Id header. Read access requires the Project viewer role and changes require the Project editor role. Read Permissions for details.
My workspace stages PATCH requests, which return 202. Creating a policy package is not staged.
Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/policy-package | Create a policy package. |
GET | /api/policy-package/{packageName} | Get a policy package with all its policies. |
PATCH | /api/policy-package/{packageName} | Add, update, rename, or remove policies, and update the package metadata. |
GET | /api/policy-package/{packageName}/policies/{policyName} | Get a single policy. |
GET | /api/policy-package/id/{id} | Get a policy package by ID, without the policies' contents. |
GET | /api/policy-package/policies/{id} | Get a policy by its version ID or stable ID. |
GET | /api/policy-package/{packageName}/export | Export the policies as a JSON file. |
POST | /api/policy-package/{packageName}/import | Import policies from a JSON file. |
The Authorization Hub interface keeps a project's policies in a single policy package named policypackage. Use this name to work with the same policies through the API.
Policy package
A policy package has the following fields:
| Field | Description |
|---|---|
id | The package ID. |
name | The package name. Unique in the project, with up to 255 characters. |
versionId | The ID of the current version. It changes with every PATCH. |
metadata | A map of strings. It holds settings such as the policy entry points and the attributes the policies use. |
policies | The policies, each with a name and its contents. |
createdAt, createdBy, updatedAt, updatedBy | Audit information. |
Create a policy package
curl -X POST "https://<authorization-hub-url>/api/policy-package" \
-H "Authorization: Bearer <access_token>" \
-H "X-Project-Id: <project-id>" \
-H "Content-Type: application/json" \
-d '{
"name": "policypackage",
"policies": [
{ "name": "access.alfa", "contents": "namespace access { policyset root { apply firstApplicable } }" }
]
}'
name is required. metadata and policies are optional. Policy names must be unique in the package and their contents cannot be blank. The response is 201 with the created package.
Update a policy package
PATCH accepts a body with metadata, policies, or both. Each change to a policy is an object in the policies array:
| Field | Required | Description |
|---|---|---|
name | Yes | The policy file name. For ADD, it is the name of the new policy. |
action | Yes | ADD, UPDATE, or REMOVE. |
contents | For ADD | The ALFA source. Required for ADD, optional for UPDATE, and ignored for REMOVE. |
newName | No | Renames the policy when action is UPDATE. |
curl -X PATCH "https://<authorization-hub-url>/api/policy-package/policypackage" \
-H "Authorization: Bearer <access_token>" \
-H "X-Project-Id: <project-id>" \
-H "Content-Type: application/json" \
-d '{
"policies": [
{ "name": "access.alfa", "action": "UPDATE", "contents": "namespace access { /* ... */ }" },
{ "name": "obsolete.alfa", "action": "REMOVE" }
]
}'
- Policies that are not mentioned in the request remain unchanged. To delete a policy, use
REMOVEexplicitly. - The request is not validated when it is staged. Problems such as unknown or duplicate policy names are reported when you promote the workspace. Read Errors when updating a policy package.
- The
metadatayou send is merged into the package's current metadata when the workspace is promoted. Keys that you do not send are kept, and any other key that you send takes your value. TheentryPointsandjsonAttributesentries are merged per policy file: your entries replace the existing ones for the policies that your changes touch, entries of other policies are kept, and entries of policies that no longer exist are dropped. - Every
PATCHcreates a new package version, even when the body is empty.
Attributes in policies
The attributes that your policies use must be defined in the package's ALFA files. The attribute-dictionary.alfa file is generated and maintained by the Authorization Hub interface from the Dictionary. You do not need to provide it when you use the API, but every attribute used by the policies must be declared in one of the files in the package, or the domain compose step fails. Read Manage policy packages using the API for details.
Authorization Hub does not compile ALFA when you save it through the API. Syntax errors and unresolved references are reported when you compose a domain.
Read policies
GET /api/policy-package/{packageName}returns the package with every policy'scontents.GET /api/policy-package/{packageName}/policies/{policyName}returns{ "name": "...", "contents": "..." }.GET /api/policy-package/id/{id}returns the package with the list ofpolicyNames, without contents.GET /api/policy-package/policies/{id}accepts either the version ID of a policy, which returns that exact historical content, or its stable ID, which returns the current content and stays the same when the policy is renamed.
Reads return the project's current policies. They never include changes staged in My workspace.
Export and import
GET /api/policy-package/{packageName}/export returns the published policies as a JSON file. The name is in the Content-Disposition header (policies_<timestamp>.json). If the package does not exist, the file contains {"metadata":{},"policies":[]}.
{
"metadata": { },
"policies": [
{ "name": "access.alfa", "contents": "namespace access { /* ... */ }" }
]
}
POST /api/policy-package/{packageName}/import takes a multipart/form-data request with the file in a part named file:
curl -X POST "https://<authorization-hub-url>/api/policy-package/policypackage/import" \
-H "Authorization: Bearer <access_token>" \
-H "X-Project-Id: <project-id>" \
-F "file=@policies.json;type=application/json"
- The file must be in the export format. Unknown properties are rejected.
- A policy name cannot contain
/, must be unique in the file, and needs non-blank contents. - The package is created if it does not exist. Policies that are identical to the current ones are skipped, and policies that are not in the file are left untouched.
The import returns 202 and stages the changes in your workspace. The body has the draftId, a summary (total, created, edited, and failed), and the items that were staged. draftId is null if nothing differs from the project. Policies that are identical to the existing ones are skipped.
Read Import and export for the behavior in the interface.
Errors
| Status | errorCode | Cause |
|---|---|---|
400 | DUPLICATE_POLICY_NAMES | Creating a package: a policy name is repeated in the request. |
400 | POLICY_CONTENTS_REQUIRED | Creating a package: a policy has blank contents. |
400 | POLICY_IMPORT_SCHEMA_INVALID | The imported file does not match the expected format. |
404 | POLICY_PACKAGE_NOT_FOUND, POLICY_NOT_FOUND, POLICY_NOT_FOUND_BY_ID | A read request names a package or policy that does not exist. |
409 | POLICY_PACKAGE_NAME_EXISTS | Creating a package: a package with this name already exists. |
Errors when updating a policy package
A PATCH request is staged in My workspace, and most of its checks are skipped when it is staged. It never returns DUPLICATE_POLICY_NAMES, POLICY_CONTENTS_REQUIRED, POLICY_NOT_FOUND, or POLICY_ALREADY_EXISTS. Instead:
- When the request is staged, the only error is
400with theDRAFT_POLICY_INVALID_ACTIONerror code, if theactionof a policy is missing or is notADD,UPDATE, orREMOVE. An update or removal of a policy that does not exist returns404with an empty body. - When the workspace is promoted, the changes are validated. A failure returns
422with theDRAFT_VALIDATION_FAILEDerror code, and each error message names the policy and one of the following problems:
| Code | Cause |
|---|---|
DRAFT_POLICY_PACKAGE_NOT_FOUND | The policy package does not exist. |
DRAFT_POLICY_NOT_FOUND | An UPDATE or REMOVE names a policy that is not in the package. |
DRAFT_POLICY_ALREADY_EXISTS | An ADD, or the newName of a rename, names a policy that already exists in the package. |
DRAFT_POLICY_MISSING_REQUIRED_FIELDS | An ADD is missing the policy name or contents. |
Read My workspace and the API.