Skip to content

Intent policy»

Intent policies control which resource operations are allowed in Intent projects and Infra Assistant Build mode. Every time a resource is created, updated, deleted, imported, or refreshed, attached Intent policies are evaluated to determine whether the operation should proceed.

Without an Intent policy attached to a project, all operations are allowed by default.

How it works»

When a resource operation is requested (through an MCP client or Infra Assistant Build mode), Spacelift evaluates all Intent policies attached to the project. Each policy receives details about the operation including the resource type, provider, operation type, and the current and proposed resource states.

Based on the policy evaluation, the operation can be:

  • Allowed: at least one allow rule matched and no deny rules matched. The operation proceeds.
  • Denied: one or more deny rules matched. The operation is blocked and the denial reasons are returned to the user.
  • Pending review: no allow or deny rules matched. The operation waits for manual approval.

If multiple Intent policies are attached to a project, they are evaluated independently and their results are combined. A single deny from any policy blocks the operation.

Rules»

Intent policies can define the following rules:

  • deny: Returns a set of strings. Each string is a reason for denying the operation. If any deny rule matches, the operation is blocked.
  • allow: Returns a set of strings. Each string is a reason for allowing the operation. At least one allow rule must match for the operation to proceed automatically.

If neither deny nor allow rules match, the operation enters a pending review state and requires manual approval.

Data input schema»

Each Intent policy evaluation receives the following input:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{
  "resource": {
    "resource_id": "string - unique identifier of the resource (e.g., 'my-instance')",
    "resource_type": "string - provider resource type (e.g., 'aws_instance', 'aws_s3_bucket')",
    "provider": "string - provider name (e.g., 'aws', 'random')",
    "provider_version": "string - provider version (e.g., '5.0.0')",
    "operation": "string - one of: 'create', 'update', 'delete', 'import', 'refresh'",
    "current_state": "object | null - current resource state (null for create operations)",
    "proposed_state": "object | null - proposed resource state (null for delete operations)"
  }
}

The current_state and proposed_state objects contain the full resource attributes as defined by the provider schema. For example, an S3 bucket's state would include fields like bucket, acl, tags, and so on.

Attaching policies to a project»

Intent policies can be attached to projects through the Spacelift UI or through an MCP client.

In the Spacelift UI:

  1. Navigate to your Intent project.
  2. Click the Policies tab.
  3. Click Attach policy and select the Intent policy you want to attach.

For step-by-step instructions with screenshots, see the Intent documentation.

Examples»

Allow only specific resource types»

This policy only allows S3 buckets and denies everything else:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package spacelift

sample := true

deny contains message if {
  input.resource.resource_type != "aws_s3_bucket"
  message := sprintf(
    "Only S3 buckets are allowed. Resource type %q is not permitted.",
    [input.resource.resource_type],
  )
}

allow contains message if {
  input.resource.resource_type == "aws_s3_bucket"
  message := sprintf(
    "Operation %q on S3 bucket is allowed.",
    [input.resource.operation],
  )
}

Deny delete operations»

This policy prevents any resource from being deleted:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package spacelift

sample := true

deny contains message if {
  input.resource.operation == "delete"
  message := sprintf(
    "Deleting %s resources is not allowed.",
    [input.resource.resource_type],
  )
}

allow contains message if {
  input.resource.operation != "delete"
  message := sprintf(
    "Operation %q on %s is allowed.",
    [input.resource.operation, input.resource.resource_type],
  )
}

Restrict operations by provider»

This policy only allows resources from the aws and random providers:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
package spacelift

sample := true

allowed_providers := {"aws", "random"}

deny contains message if {
  not input.resource.provider in allowed_providers
  message := sprintf(
    "Provider %q is not allowed. Permitted providers: %v.",
    [input.resource.provider, allowed_providers],
  )
}

allow contains message if {
  input.resource.provider in allowed_providers
  message := sprintf(
    "Provider %q is allowed.",
    [input.resource.provider],
  )
}

Require tags on resources»

This policy denies creation of S3 buckets without an Environment tag:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package spacelift

sample := true

deny contains message if {
  input.resource.resource_type == "aws_s3_bucket"
  input.resource.operation == "create"
  not input.resource.proposed_state.tags.Environment
  message := "S3 buckets must have an Environment tag."
}

allow contains message if {
  input.resource.resource_type == "aws_s3_bucket"
  input.resource.proposed_state.tags.Environment
  message := sprintf(
    "S3 bucket with Environment=%s is allowed.",
    [input.resource.proposed_state.tags.Environment],
  )
}