此内容没有您所选择的语言版本。
Chapter 7. Implementing policy enforcement
Policy enforcement at automation runtime is a feature that uses encoded rules to define, manage, and enforce policies that govern how your users interact with your Ansible Automation Platform instance. Policy enforcement automates policy management, improving security, compliance, and efficiency.
OPA, or Open Policy Agent, is a policy engine that offloads policy decisions from your Ansible instance. When it is triggered, the policy enforcement feature connects to OPA to retrieve policies specified in your configuration, and applies policy rules to your automation content. If OPA detects a policy violation, it will stop the action and give your user information about the policy violation.
Prerequisites
Before you can implement policy enforcement in your Ansible Automation Platform instance, you must have:
-
An Ansible Automation Platform 2.5 deployment with the
FEATURE_POLICY_AS_CODE_ENABLED
feature flag set toTRUE
. - Access to an OPA server that is reachable from your Ansible Automation Platform deployment.
- Configured Ansible Automation Platform with settings required for authenticating to your OPA server.
- Some familiarity with OPA and the Rego language, which is the language policies are written in.
OPA API V1 is the only version currently supported in Ansible Automation Platform.
7.1. Enabling policy enforcement
During installation, you must configure your Ansible Automation Platform instance to include the policy enforcement feature. You can do this by modifying the feature flag variables in your configuration file. Follow the instructions below relevant to your installation type.
OpenShift Container Platform Installation
For OpenShift Container Platform installations, you must modify the Ansible Automation Platform custom resource. Add the following to the spec section:
spec: feature_flags: FEATURE_POLICY_AS_CODE_ENABLED: True
spec:
feature_flags:
FEATURE_POLICY_AS_CODE_ENABLED: True
After applying the changes, wait for the operator to complete the update process. The operator automatically handles the necessary service restarts and configuration updates.
RPM Installation
For RPM-based installations, modify the inventory file used by the installer to add the following variable:
feature_flags: FEATURE_POLICY_AS_CODE_ENABLED: True
feature_flags:
FEATURE_POLICY_AS_CODE_ENABLED: True
See Defining variables at runtime for more on adding vars. After modifying the inventory file, rerun the installer to apply changes.
Containerized Installation
For containerized installations, modify the inventory file used by the installer to add:
feature_flags: FEATURE_POLICY_AS_CODE_ENABLED: True
feature_flags:
FEATURE_POLICY_AS_CODE_ENABLED: True
After modifying the inventory file, rerun the installer to apply the changes.
Verifying feature flag status
To verify that the feature flag is enabled, you can check the feature flags state endpoint:
https://<your-aap-host>/api/controller/v2/feature_flags_state/
https://<your-aap-host>/api/controller/v2/feature_flags_state/
The endpoint will return a JSON
response containing the current state of all feature flags, including FEATURE_POLICY_AS_CODE_ENABLED
.
Additional resources
7.2. Configuring policy enforcement settings
You can specify how your Ansible Automation Platform instance interacts with OPA by modifying your global settings.
Procedure
-
From the navigation panel, select
. - Click Edit policy settings.
On the Policy Settings page, fill out the following fields:
- OPA Server hostname
- Enter the name of the host that connects to the OPA service.
- OPA server port
- Enter the port that connects to the OPA service.
- OPA authentication type
- Select the OPA authentication type.
- OPA custom authentication header
- Enter a custom header to be appended to request headers for OPA authentication.
- OPA request timeout
- Enter the number of seconds until the connection times out.
- OPA request retry count
- Enter a figure for the number of times a request can attempt to connect to the OPA service before failing.
Depending on your authentication type, you may need to fill out the following fields.
If you selected Token as your authentication type:
- OPA authentication token
- Enter the OPA authentication token.
If you selected Certificate as your authentication type:
- OPA client certificate content
- Enter content of the CA certificate for mTLS authentication.
- OPA client key content
- Enter the client key for mTLS authentication.
- OPA CA certificate content
- Enter the content of the CA certificate for mTLS authentication.
Beneath the heading labeled Options:
- Use SSL for OPA connection
- Check this box to enable an SSL connection to the OPA service.
- Click .
7.3. Understanding OPA packages and rules
An OPA policy is organized in packages, which are namespaced collections of rules. The basic structure of an OPA policy looks like this:
package aap_policy_examples # Package name import rego.v1 # Import required for Rego v1 syntax # Rules define the policy logic allowed := { "allowed": true, "violations": [] }
package aap_policy_examples # Package name
import rego.v1 # Import required for Rego v1 syntax
# Rules define the policy logic
allowed := {
"allowed": true,
"violations": []
}
The key components of the rule’s structure are:
- Package declaration
- This defines the namespace for your policy.
- Rules
- This defines the policy’s logic and the decision that it returns.
These components together comprise the OPA policy name, which is formatted as [package]/[rule]
. You will enter the OPA policy name when you configure enforcement points.
7.4. Configuring enforcement points
After you have set up your Ansible Automation Platform instance to communicate with the OPA server, you can set up enforcement points where you want the policy to be applied.
You can associate a policy with a job template, an inventory, or an organization. Enforcement then occurs in the following ways:
- Organization
- Jobs launched from a template owned by an organization will fail if the policy is violated. This configuration provides broad control over automation within organizational boundaries.
- Inventory
- Jobs using an inventory associated with a policy fail if the policy is violated. This configuration allows you to control access to specific infrastructure resources.
- Job template
- Jobs launched from a template associated with a policy fail if the job violates the associated policy. This configuration provides granular control over specific automation tasks.
7.4.1. Associating a policy with an organization
To associate a policy with an organization, take the following steps.
Procedure
-
From the navigation panel, select
. On the Organizations page:
-
To edit an existing organization, find the organization you want to edit and click the pencil icon
to go to the editing screen.
- To create a new organization, click .
-
To edit an existing organization, find the organization you want to edit and click the pencil icon
-
In the field labeled Policy enforcement, enter the query path associated with the policy you want to implement. Note that the query path must be formatted as
package/rule
. - Click and then to save your settings.
7.4.2. Associating a policy with an inventory
To associate a policy with an inventory, take the following steps:
Procedure
-
From the navigation panel, select
. On the Inventories page:
-
To edit an existing inventory, find the inventory you want to edit and click the pencil icon
to go to the editing screen.
- To create a new inventory, click .
-
To edit an existing inventory, find the inventory you want to edit and click the pencil icon
-
In the field titled Policy enforcement, enter the query path associated with the policy you want to implement. Note that the query path must be formatted as
package/rule
. - Click if you are editing an existing inventory, or click if you are creating a new inventory.
7.4.3. Associating a policy with a job template
To associate a policy with a job template, take the following steps:
Procedure
-
From the navigation panel, select
. On the Automation Templates page:
-
To edit an existing job template, find the job template you want to edit and click the pencil icon
to go to the editing screen.
- To create a new job template, click .
-
To edit an existing job template, find the job template you want to edit and click the pencil icon
-
In the field titled Policy enforcement, enter the query path associated with the policy you want to implement. Note that the query path must be formatted as
package/rule
. - Click if you are editing an existing job template, or click if you are creating a new job template.
7.5. Policy enforcement inputs and outputs
Use the following inputs and outputs to craft policies for use in policy enforcement.
Input | Type | Description |
---|---|---|
| Integer | The job’s unique identifier. |
| String | Job template name. |
| Datetime (ISO 8601) | Timestamp indicating when the job was created. |
| Object | Information about the user who created the job.
|
| List of objects | Credentials associated with job execution.
|
| Object | Details about the execution environment used for the job.
|
| JSON | Extra variables provided for job execution. |
| Integer | The number of parallel processes used for job execution. |
| Integer | The number of hosts targeted by the job. |
| Object | Information about the instance group handling the job, including:
|
| Object | Inventory details used in the job execution, including:
|
| Object | Information about the job template, including:
|
| Choice (String) | Type of job execution. Allowed values are:
|
| String | Human-readable name for the job type. |
| List of objects | Labels associated with the job, including:
|
| Choice (String) | How the job was launched. Allowed values include:
|
| String | The limit applied to the job execution. |
| Object | Information about the user who launched the job, including:
|
| Object | Information about the organization associated with the job, including:
|
| String | The playbook used in the job execution. |
| Object | Details about the project associated with the job, including:
|
| String | The specific branch to use for SCM. |
| String | SCM revision used for the job. |
| Object | Workflow job details, if the job is part of a workflow. |
| Object | Workflow job template details. |
Example
The following code block shows example input data from a demo job template launch:
{ "id": 70, "name": "Demo Job Template", "created": "2025-03-19T19:07:03.329426Z", "created_by": { "id": 1, "username": "admin", "is_superuser": true, "teams": [] }, "credentials": [ { "id": 3, "name": "Example Machine Credential", "description": "", "organization": null, "credential_type": 1, "managed": false, "kind": "ssh", "cloud": false, "kubernetes": false } ], "execution_environment": { "id": 2, "name": "Default execution environment", "image": "registry.redhat.io/ansible-automation-platform-25/ee-supported-rhel8@sha256:b9f60d9ebbbb5fdc394186574b95dea5763b045ceff253815afeb435c626914d", "pull": "" }, "extra_vars": { "example": "value" }, "forks": 0, "hosts_count": 0, "instance_group": { "id": 2, "name": "default", "capacity": 0, "jobs_running": 1, "jobs_total": 38, "max_concurrent_jobs": 0, "max_forks": 0 }, "inventory": { "id": 1, "name": "Demo Inventory", "description": "", "kind": "", "total_hosts": 1, "total_groups": 0, "has_inventory_sources": false, "total_inventory_sources": 0, "has_active_failures": false, "hosts_with_active_failures": 0, "inventory_sources": [] }, "job_template": { "id": 7, "name": "Demo Job Template", "job_type": "run" }, "job_type": "run", "job_type_name": "job", "labels": [ { "id": 1, "name": "Demo label", "organization": { "id": 1, "name": "Default" } } ], "launch_type": "workflow", "limit": "", "launched_by": { "id": 1, "name": "admin", "type": "user", "url": "/api/v2/users/1/" }, "organization": { "id": 1, "name": "Default" }, "playbook": "hello_world.yml", "project": { "id": 6, "name": "Demo Project", "status": "successful", "scm_type": "git", "scm_url": "https://github.com/ansible/ansible-tower-samples", "scm_branch": "", "scm_refspec": "", "scm_clean": false, "scm_track_submodules": false, "scm_delete_on_update": false }, "scm_branch": "", "scm_revision": "", "workflow_job": { "id": 69, "name": "Demo Workflow" }, "workflow_job_template": { "id": 10, "name": "Demo Workflow", "job_type": null } }
{
"id": 70,
"name": "Demo Job Template",
"created": "2025-03-19T19:07:03.329426Z",
"created_by": {
"id": 1,
"username": "admin",
"is_superuser": true,
"teams": []
},
"credentials": [
{
"id": 3,
"name": "Example Machine Credential",
"description": "",
"organization": null,
"credential_type": 1,
"managed": false,
"kind": "ssh",
"cloud": false,
"kubernetes": false
}
],
"execution_environment": {
"id": 2,
"name": "Default execution environment",
"image": "registry.redhat.io/ansible-automation-platform-25/ee-supported-rhel8@sha256:b9f60d9ebbbb5fdc394186574b95dea5763b045ceff253815afeb435c626914d",
"pull": ""
},
"extra_vars": {
"example": "value"
},
"forks": 0,
"hosts_count": 0,
"instance_group": {
"id": 2,
"name": "default",
"capacity": 0,
"jobs_running": 1,
"jobs_total": 38,
"max_concurrent_jobs": 0,
"max_forks": 0
},
"inventory": {
"id": 1,
"name": "Demo Inventory",
"description": "",
"kind": "",
"total_hosts": 1,
"total_groups": 0,
"has_inventory_sources": false,
"total_inventory_sources": 0,
"has_active_failures": false,
"hosts_with_active_failures": 0,
"inventory_sources": []
},
"job_template": {
"id": 7,
"name": "Demo Job Template",
"job_type": "run"
},
"job_type": "run",
"job_type_name": "job",
"labels": [
{
"id": 1,
"name": "Demo label",
"organization": {
"id": 1,
"name": "Default"
}
}
],
"launch_type": "workflow",
"limit": "",
"launched_by": {
"id": 1,
"name": "admin",
"type": "user",
"url": "/api/v2/users/1/"
},
"organization": {
"id": 1,
"name": "Default"
},
"playbook": "hello_world.yml",
"project": {
"id": 6,
"name": "Demo Project",
"status": "successful",
"scm_type": "git",
"scm_url": "https://github.com/ansible/ansible-tower-samples",
"scm_branch": "",
"scm_refspec": "",
"scm_clean": false,
"scm_track_submodules": false,
"scm_delete_on_update": false
},
"scm_branch": "",
"scm_revision": "",
"workflow_job": {
"id": 69,
"name": "Demo Workflow"
},
"workflow_job_template": {
"id": 10,
"name": "Demo Workflow",
"job_type": null
}
}
Input | Type | Description |
---|---|---|
| Boolean | Indicates whether the action is permitted |
| List of strings | Reasons why the action is not permitted |
Example
The following code block shows an example of expected output from the OPA policy query:
{ "allowed": false, "violations": [ "No job execution is allowed", ... ], ... }
{
"allowed": false,
"violations": [
"No job execution is allowed",
...
],
...
}