Skip to content

Using ABAC Authorization

Attribute-based access control (ABAC) defines an access control paradigm whereby access rights are granted to users with policies that combine attributes together.

Policy File Format

To enable ABAC mode for a service, specify --authorization-policy-file=SOME_FILENAME and --authorization-mode=ABAC command-line options on startup. You must also specify a ‘static tokens’ file using the --token-auth-file command line option.


If you are using one of the provided Docker images, use the OPENTF_AUTHORIZATION_POLICY_FILE, OPENTF_AUTHORIZATION_MODE, and OPENTF_TOKEN_AUTH_FILE environment variables instead. Those settings will apply to every service launched by the image.

The file format is one JSON object per line. There should be no enclosing list or map, only one map per line.

Empty lines and lines starting with a # character are ignored as comments.

Each line is a “policy object”, where each such object is a map with the following properties:

  • Versioning properties:

    • apiVersion, type string; valid value is Allows versioning and conversion of the policy format.
    • kind, type string; valid value is Policy. Allows versioning and conversion of the policy format.
  • spec property set to a map with the following properties:

    • Subject-matching properties:
      • user, type string; the user ID from --token-auth-file. If you specify user, it must match the user ID of the authenticated user.
      • group, type string; if you specify group, it must match one of the groups of the authenticated user.
    • Resource-matching properties:
      • apiGroup, type string; an API group.
        • Ex: extensions
        • Wildcard: * matches all API groups.
      • namespace, type string; a namespace
        • Ex: default
        • Wildcard: * matches all namespaces.
      • resource, type string; a resource type
        • Ex: workflows
        • Wildcard: * matches all resources.
    • readonly, type boolean, when true, means that the Resource-matching policy only applies to get, list, and watch operations.


An unset property is the same as a property set to the zero value for its type (e.g., empty string, 0, false). However, unset should be preferred for readability.

In the future, policies may be expressed in a JSON format, and managed via a REST interface.

Available API Groups

API groups are collections of resources. Each resource belongs to an API group.

Resources are of the form {apiGroup}/{version}/{resource}. API groups are of the form, versions are of the form v1 or v1alpha1, and resources are simple names like Workflows.

This field can be used to disambiguate resources that have the same name in different API groups.

This field is not used yet, use "*" as its value.

Available Resources

In addition to the "*" wildcard, which matches all resources, the following resources can be used:

  • agents
  • channelhandlers
  • channels
  • qualitygates
  • status
  • subscriptions
  • workflows

Authorization Algorithm

A request has attributes that correspond to the properties of a policy object.

When a request is received, the attributes are determined. Unknown attributes are set to the zero value of their type (e.g. empty string, 0, false).

A property set to "*" will match any value of the corresponding attribute.

The tuple of attributes is checked for a match against every policy in the ‘policy’ file. If at least one line matches the request attributes, then the request is authorized (but may fail later validation).

To permit a user to do anything, write a policy with the apiGroup, namespace, and resource properties set to "*".

If no policy is associated with a user defined in the ‘static token’ file, or if no policy matches the request, the request is denied.


This section builds on the “Static Token File” example, which is:

ey...,Alice Doe,alice
ey...,Bob Doe,bob,"team_a,team_b"

Alice can do anything with all resources

{"apiVersion": "", "kind": "Policy", "spec": {"user": "alice", "namespace": "*", "resource": "*", "apiGroup": "*"}}

Bob can read workflows in namespace “projectCaribou”

{"apiVersion": "", "kind": "Policy", "spec": {"user": "bob", "namespace": "projectCaribou", "resource": "workflows", "readonly": true}}

Members of the “team_a” group have access to all resources in the project-a namespace

{"apiVersion": "", "kind": "Policy", "spec": {"group": "team_a", "namespace": "project-a", "resource": "*", "apiGroup": "*"}}

All together

Alice can do anything with all resources. Bob can read workflows in namespace “projectCaribou” and can do anything in resources in namespace “project-a”, as he is a member of the “team_a” group.

{"apiVersion": "", "kind": "Policy", "spec": {"user": "alice", "namespace": "*", "resource": "*", "apiGroup": "*"}}
{"apiVersion": "", "kind": "Policy", "spec": {"user": "bob", "namespace": "projectCaribou", "resource": "workflows", "readonly": true}}
{"apiVersion": "", "kind": "Policy", "spec": {"group": "team_a", "namespace": "project-a", "resource": "*", "apiGroup": "*"}}