Policy Types
Policies within the StackGuardian platform serve as a set of rules or guardrails, enforceable on workflows or cloud infrastructure. These policies facilitate a self-service model with granular control.
Custom Policy Frameworksβ
For specialized policy requirements:
- Tirith (StackGuardian Policy Framework), Explore a JSON-based framework designed for IaC & workflow compliance.
- Open Policy Agent, Utilize detailed policy definitions using the Rego language.
Discover more about StackGuardian policies here.
Types of Enforceable Policiesβ
StackGuardian's Tirith engine supports a variety of policies for efficient and secure cloud infrastructure management:
1. Infrastructure Policiesβ
- Enforce Terraform best practices and configurations. Example: Enforce VPCs to use default tenancy.
2. Workflow and Stack Policiesβ
-
Enforce custom compliance and guardrail rules for Workflows and Stacks with approval processes for security and efficiency. Example: Approval required for changes to production environments.
-
Workflow and Stack policies can also be used in conjunction with Context Tags to reference the attributes of a dependent Workflow or Stack in the policy. Example: Block the execution of a Workflow/Stack until a certain Workflow/Stack has a
COMPLETED
status.
Tip: A policy with an evaluator that uses a
${curr_workflow
reference will only apply to Workflows. Similarly, if${curr_stack
is used, it will only apply to Stacks. Generic policies (without thesecurr_
references) will be applied to both Workflows and Stacks, depending on the Policy Enforcement configuration.
π Click here to view an example of a Workflow Policy using Context Tags.
π Click here to view an example of a Stack Policy using Context Tags.
3. Cost Control Policies (Upcoming)β
- Implement budget limits and dynamic cost optimization. Example: Limit EC2 monthly costs to under $100
4. Security and Compliance Policiesβ
- Apply security measures and meet compliance standards (e.g., CIS, PCI DSS). Example: Ensure all security groups block inbound SSH from the public internet.
5. Tagging and Resource Management Policiesβ
- Require consistent tagging for all resources for better management. Example: Enforce 'Environment' and 'Owner' tags on all resources.
6. Drift Detection and Continuous Complianceβ
- Detect and correct configuration drifts to maintain continuous compliance. Example: Alert on unapproved changes to infrastructure.
Access or subscribe to policies via the StackGuardian Marketplace, or create customized policies using the Open Policy Agent or the StackGuardian Policy Framework.
Policy Structure and Configurationβ
Scope Configurationβ
Under Meta tab, you can find Scope configuration, which tells StackGuardian where you want to enforce this policy. We automatically determine the type of the policy and enforce it on the workflow or infrastructure configuration as appropriate.
Tip: You can use 200+ of cloud best practice policies already available in the Marketplace or create new ones too.
Each policy comprises multiple rules that, upon evaluation, influence a workflow run. These are determined by "Action when policy passes" and "Action when policy errors" settings, with the option to bypass certain rules if needed.
Implementing Policiesβ
Marketplace Policy Templatesβ
Easily adopt Marketplace templates by subscribing to them within the StackGuardian Marketplace, allowing for a simplified policy application process.
Open Policy Agent Integrationβ
On StackGuardian you will find first class support for Open Policy Agent and you can source your Rego configuration from a GitHub or git based repository.
Follow these steps to configure an OPA policy inside a rule:
- Uncheck Marketplace Policy Template and choose Source Config Kind as "Open Policy Agent.
- Select version control system where you have stored your Rego policies, either "github.com or "git (other)".
- Provide Repository URL and optionally git reference and working directory, unless you want to use the defaults configured in your repo.
- If you have a private repository, you can either use a secret stored in your StackGuardian Vault by specifying "/secrets/some-vault-secret" or github_com integration by exactly specifying "/integrations/github_com" in the Authentication method*" field. In case you are using
git (other)
, StackGuardian will use the value of the specified secret to build a git URL with authentication information. For Bitbucket for example, the specified vault secret should have the secret value in the following format USERNAME:APP_PASSWORD which will result in the following git URLhttps://USERNAME:APP_PASSWORD@bitbucket.org/username/reposlug.git
that StackGuardian will use to fetch the policy configuration.
- Under Additional Config, you can optionally provide OPA Deciding Query, which StackGuardian will use to decide the final policy result. This query should return a boolean which is currently supported. It can be provided in the following format: "
<opa-package-path>.<rule-name-returning-boolean>
". OPA Deciding Query use to be a required attribute but now it is optional. We will keep on supportingOPA Deciding Query
like before. - Finally, you can optionally use the Code Editor to pass JSON that StackGuardian will pass to OPA runtime as policy data. This enables you to template your Rego policies and reuse them to build different policies.
Tirith: StackGuardian Policy Frameworkβ
The Tirith Policy Framework by StackGuardian offers a user-friendly alternative to OPA for policy enforcement, directly integrating with code editors and planning support for git-based policy management. Designed for simplicity, Tirith facilitates the scanning of Terraform and CloudFormation configurations, making policy definition and enforcement straightforward without delving into complexities. This approach ensures easy compliance with infrastructure policies. For more details, visit the GitHub repository.
Examplesβ
Prevent accidental delete of VPCβ
Set VPC default tenancy and safeguard EC2 instances against deletion
Using Code-Editorβ
{
"meta": {
"required_provider": "stackguardian/terraform_plan",
"version": "v1"
},
"evaluators": [
{
"description": "",
"condition": {
"type": "NotEquals",
"value": "delete",
"error_tolerance": 1
},
"id": "eval-id-1",
"provider_args": {
"operation_type": "action",
"terraform_resource_attribute": "",
"terraform_resource_type": "aws_vpc"
}
}
],
"eval_expression": "eval-id-1"
}
Using No-Codeβ
Cost control policy (Terraform)β
EC2 instance cost is lower than 100 USD per month
Using Code-Editorβ
{
"meta": {
"required_provider": "stackguardian/infracost",
"version": "v1"
},
"evaluators": [
{
"provider_args": {
"operation_type": "total_monthly_cost",
"resource_type": ["aws_ec2"]
},
"condition": {
"type": "LessThanEqualTo",
"value": 100
},
"id": "ec2_cost_below_100_per_month"
}
],
"eval_expression": "ec2_cost_below_100_per_month"
}
Using No-Codeβ
Scheduling Policyβ
Ensure enabled cron jobs for destroy action workflows
Using Code-Editorβ
{
"meta": {
"required_provider": "stackguardian/json",
"version": "v1"
},
"evaluators": [
{
"description": "Cron job exists for the workflow",
"condition": {
"type": "IsNotEmpty",
"value": "",
"error_tolerance": 0
},
"id": "eval-id-1",
"provider_args": {
"operation_type": "get_value",
"key_path": "UserSchedules.*.cron"
}
},
{
"description": "Action must be destroy",
"condition": {
"type": "ContainedIn",
"value": [["destroy"]],
"error_tolerance": 0
},
"id": "eval-id-2",
"provider_args": {
"operation_type": "get_value",
"key_path": "UserSchedules.*.inputs.TerraformAction.action"
}
},
{
"description": "Schedule must be enabled",
"condition": {
"type": "ContainedIn",
"value": [["ENABLED"]],
"error_tolerance": 0
},
"id": "eval-id-3",
"provider_args": {
"operation_type": "get_value",
"key_path": "UserSchedules.*.state"
}
}
],
"eval_expression": "eval-id-1 && eval-id-2 && eval-id-3"
}
Using No-Codeβ
Tagging Policyβ
Validate 'costcenter:workshop' tag on AWS EKS node groups
Using Code-Editorβ
{
"meta": {
"required_provider": "stackguardian/terraform_plan",
"version": "v1"
},
"evaluators": [
{
"description": "",
"condition": {
"type": "Contains",
"value": {
"costcenter": "workshop"
},
"error_tolerance": 1
},
"id": "eval-id-1",
"provider_args": {
"operation_type": "attribute",
"terraform_resource_attribute": "tags",
"terraform_resource_type": "aws_eks_node_group"
}
}
],
"eval_expression": "eval-id-1"
}
Using No-Codeβ
Workflow Policy Using Context Tagsβ
Use a Workflow Policy to restrict execution of a production Workflow until the staging Workflow has completed successfully for an apply action with the same template group ID and revision.
This policy uses Context Tags to reference a dependent Workflow and checks for several conditions:
- The dependent Workflow must have a status of
COMPLETED
. - The dependent Workflow must have performed an
apply
action. - The dependent Workflowβs
iacTemplateId
must be less than or equal to that of the current workflow.
To reference another workflow, use the ${workflow::...}
syntax. For example, you can reference a workflow directly by using ${workflow::workflowGroupName.workflowName}
where you replace workflowGroupName
and workflowName
with the actual values.
In this scenario, the current workflow has a context tag named depWf
, which stores a reference to another workflow. You can access attributes of the current workflow using ${curr_workflow.attrs...}
within a workflow reference string.
Workflow reference strings are evaluated from the innermost key outward. For example:
${workflow::${curr_workflow.attrs.ContextTags.depWf}.attrs.LatestWfrunStatus}
This expression works as follows:
- It first retrieves the value of the context tag named
depWf
from the current workflow. - It then uses this value to reference the dependent workflow.
- Finally, it fetches the
LatestWfrunStatus
attribute from the dependent workflow.
This allows you to create dynamic policies that depend on the state or attributes of other workflows, enabling advanced automation and governance scenarios.
Using Code-Editorβ
{
"evaluators": [
{
"provider_args": {
"operation_type": "get_value",
"key_path": "${workflow::${curr_workflow.attrs.ContextTags.depWf}.attrs.LatestWfrunStatus}"
},
"condition": {
"type": "Equals",
"value": "COMPLETED"
},
"id": "dependent_workflow_completed"
},
{
"provider_args": {
"operation_type": "get_value",
"key_path": "${workflow::${curr_workflow.attrs.ContextTags.depWf}.attrs.LatestTerraformAction}"
},
"condition": {
"type": "Equals",
"value": "apply"
},
"id": "dependent_workflow_applied"
},
{
"provider_args": {
"operation_type": "get_value",
"key_path": "VCSConfig.iacVCSConfig.iacTemplateId"
},
"condition": {
"type": "LessThanEqualTo",
"value": "${workflow::${curr_workflow.attrs.ContextTags.depWf}.attrs.VCSConfig.iacVCSConfig.iacTemplateId}"
},
"id": "staging_template_version_greater_equal"
}
],
"meta": {
"required_provider": "stackguardian/json",
"version": "v1"
},
"eval_expression": "dependent_workflow_completed && dependent_workflow_applied && staging_template_version_greater_equal"
}
Stack Policy Using Context Tagsβ
Use a Stack Policy to restrict execution of a Production stack until a Staging Stack has completed successfully with the same template group ID and revision.
This policy uses Context Tags to reference a dependent Stack and checks for several conditions:
- The template group ID (the template revision) of the current stack must be equal to that of the dependent stack.
- The dependent Stack must have a status of
COMPLETED
. - The resource name of the Stack must contain
prod-
.
To reference another stack, use the ${stack::...}
syntax. For example, you can reference a stack directly by using ${stack::workflowGroupName.stackName}
where you replace workflowGroupName
and stackName
with the actual values.
In this scenario, the current stack has a context tag named depStack
, which stores a reference to another stack. You can access attributes of the current stack using ${curr_stack.attrs...}
within a stack reference string.
Stack reference strings are evaluated from the innermost key outward. For example:
${stack::${curr_stack.attrs.ContextTags.depStack}.attrs.LatestWfStatus}
This expression works as follows:
- It first retrieves the value of the context tag named
depStack
from the current stack. - It then uses this value to reference the dependent stack.
- Finally, it fetches the
LatestWfStatus
attribute from the dependent stack.
This allows you to create dynamic policies that depend on the state or attributes of other stacks, enabling advanced automation and governance scenarios.
Using Code-Editorβ
{
"evaluators": [
{
"description": "",
"id": "current_template_version_matches_dependent_stack",
"provider_args": {
"operation_type": "get_value",
"key_path": "TemplateGroupId"
},
"condition": {
"type": "Equals",
"value": "${stack::${curr_stack.attrs.ContextTags.depStack}.attrs.TemplateGroupId}",
"error_tolerance": 0
}
},
{
"provider_args": {
"operation_type": "get_value",
"key_path": "${stack::${curr_stack.attrs.ContextTags.depStack}.attrs.LatestWfStatus}"
},
"condition": {
"type": "Equals",
"value": "COMPLETED"
},
"id": "dependent_stack_completed"
},
{
"provider_args": {
"operation_type": "get_value",
"key_path": "ResourceName"
},
"condition": {
"type": "Contains",
"value": "prod-"
},
"id": "resource_name_contains_prod"
}
],
"meta": {
"required_provider": "stackguardian/json",
"version": "v1"
},
"eval_expression": "resource_name_contains_prod && current_template_version_matches_dependent_stack && dependent_stack_completed"
}