Skip to main content

Using Harness Policy As Code with Feature Management & Experimentation

Last updated on

Harness Policy As Code lets FME administrators define governance rules that are automatically evaluated whenever feature flags or feature flag definitions are created, updated, deleted, or archived. Policies are authored in Rego and evaluated using Open Policy Agent (OPA).

Harness provides out-of-the-box policies for Feature Management & Experimentation (FME). These policies cover common governance requirements across feature flags, environments, and segments.

FME EntityOut-of-the-box Policies
Feature FlagsNaming Convention, Required Tags, Team Ownership Required
Feature Flag DefinitionsValidation Rules
EnvironmentsNaming Convention, Production Requires Approvals
SegmentsNaming Convention
Segment DefinitionsValidation Rules, Exclude High Priority Users

All policies are evaluated on On Save events across these entities. Policies apply across feature flag lifecycle, rollout configuration, targeting logic, and environment governance controls.

Prerequisites

Input payload reference

When a policy is evaluated, Harness sends an input payload to OPA containing the entity data and metadata. The payload structure depends on the entity type.

Feature Flag
Feature Flag Policy Evaluation Input Payload
{
"featureFlag": {
"name": "enable_dark_mode",
"status": "ACTIVE",
"description": "Enable dark mode for end users",
"trafficTypeName": "user",
"tags": ["ui", "frontend"],
"keyMetrics": ["metric_login_success_rate"],
"supportingMetrics": ["metric_error_rate"],
"rolloutStatusName": "rollout_in_progress",
"pendingChangeRequests": 0,
"hasPendingStatusChange": false,
"lastTrafficDate": "2025-02-08T00:00:00Z",
"governanceType": "fmeFeatureFlag"
},
"entityMetadata": {
"actor": {
"type": "user",
"name": "Jane Smith"
},
"account": {
"accountId": "abc123",
"organizationId": "org_456"
},
"project": {
"id": "mobile_shopping_app"
},
"owners": [
{
"ownerType": "team",
"ownerId": "team_frontend",
"ownerName": "Frontend Team"
}
],
"changeTrigger": "update"
}
}

The following policy denies creating or updating a feature flag if the description is missing or empty. It uses changeTrigger to skip validation on delete, so that flags with missing descriptions can still be cleaned up. For more examples, see FME policy samples.

Require a description for feature flags
package fme_feature_flags

deny[msg] {
input.entityMetadata.changeTrigger != "delete"
not input.featureFlag.description
msg := sprintf(
"Feature flag '%s' must include a description before it can be saved",
[input.featureFlag.name]
)
}

deny[msg] {
input.entityMetadata.changeTrigger != "delete"
input.featureFlag.description == ""
msg := sprintf(
"Feature flag '%s' must include a non-empty description",
[input.featureFlag.name]
)
}
Feature Flag Definition
Feature Flag Definition Policy Evaluation Input Payload
{
"featureFlagDefinition": {
"name": "enable_dark_mode",
"environmentName": "Production",
"status": "ACTIVE",
"killed": false,
"trafficTypeName": "user",
"description": "Enable dark mode for end users",
"definition": [
{
"conditionType": "ROLLOUT",
"matcherGroup": {
"combiner": "AND",
"matchers": [
{
"matcherType": "ALL_KEYS",
"negate": false
}
]
},
"partitions": [
{
"treatment": "off",
"size": 100
}
],
"label": "Default treatment"
}
],
"treatments": [
{
"name": "on",
"description": "Enable dark mode",
"baseline": false,
"defaultTreatment": false
},
{
"name": "off",
"description": "Keep dark mode disabled",
"baseline": true,
"defaultTreatment": true
}
],
"trafficAllocation": 100,
"flagSets": []
},
"entityMetadata": {
"actor": {
"type": "user",
"name": "Jane Smith"
},
"account": {
"accountId": "abc123",
"organizationId": "org_456"
},
"project": {
"id": "mobile_shopping_app"
},
"owners": [
{
"ownerType": "team",
"ownerId": "team_frontend",
"ownerName": "Frontend Team"
}
],
"changeTrigger": "update"
}
}

The following policy ensures that every feature flag definition saved in a production environment belongs to at least one flag set. For additional examples, see FME Feature Flag Definition policy samples.

Require flag sets for production definitions
package fme_feature_flag_definitions

deny[msg] {
lower(input.featureFlagDefinition.environmentName) == "production"
count(input.featureFlagDefinition.flagSets) == 0
msg := sprintf(
"Feature flag '%s' in Production must belong to at least one flag set",
[input.featureFlagDefinition.name]
)
}
Environment
FME Environment Policy Evaluation Input Payload
{
"fmeEnvironment": {
"name": "production"
},
"entityMetadata": {
"actor": {
"type": "user",
"name": "Jane Smith"
},
"account": {
"accountId": "abc123",
"organizationId": "org_456"
},
"project": {
"id": "mobile_shopping_app"
},
"changeTrigger": "update"
}
}

The following policy enforces naming conventions for FME environments.

Enforce naming conventions for FME environments
package fme_environments

deny[msg] {
not regex.match("^[a-z][a-z0-9_]*$", input.fmeEnvironment.name)
msg := sprintf(
"FME Environment name '%s' must start with a lowercase letter and contain only lowercase letters, numbers, and underscores",
[input.fmeEnvironment.name]
)
}
Segment
FME Segment Policy Evaluation Input Payload
{
"fmeSegment": {
"name": "beta_users"
},
"entityMetadata": {
"actor": {
"type": "user",
"name": "Jane Smith"
},
"account": {
"accountId": "abc123",
"organizationId": "org_456"
},
"project": {
"id": "mobile_shopping_app"
},
"changeTrigger": "update"
}
}

The following policy enforces naming conventions for FME segments.

Enforce naming conventions for FME segments
package fme_segments

deny[msg] {
not regex.match("^[a-z][a-z0-9_]*$", input.fmeSegment.name)
msg := sprintf(
"FME Segment name '%s' must follow naming conventions",
[input.fmeSegment.name]
)
}
Segment Definition
FME Segment Definition Policy Evaluation Input Payload
{
"fmeSegmentDefinition": {
"name": "beta_users",
"type": "rule_based",
"rules": [
{
"attribute": "country",
"operator": "equals",
"values": ["US"]
}
],
"excludedSegments": ["high_priority_users"]
},
"entityMetadata": {
"actor": {
"type": "user",
"name": "Jane Smith"
},
"account": {
"accountId": "abc123",
"organizationId": "org_456"
},
"project": {
"id": "mobile_shopping_app"
},
"changeTrigger": "update"
}
}

The following policy ensures that rule-based segment definitions exclude the high priority users segment.

Require rule-based segments to exclude high priority users
package fme_segment_definitions

deny[msg] {
input.fmeSegmentDefinition.type == "rule_based"
not "high_priority_users" in input.fmeSegmentDefinition.excludedSegments
msg := sprintf(
"Segment '%s' must exclude the high priority users segment",
[input.fmeSegmentDefinition.name]
)
}

Access Harness policies

When you navigate to the Policies page from Project, Account, or Organization Settings, you can manage policies, policy sets, and evaluations across the following tabs.

The Overview tab displays a high-level view of policy health across your project, account, or organization. This includes charts for policy evaluations, summary counts for policy sets and total evaluations, and the total number of policies.

Policy health overview dashboard

Click the dropdown menu to view the policy health in the Last 24 hours, Last 7 days, and Last 30 days. Use this view to understand how policies are performing and whether violations are increasing or decreasing.

Create and enforce a policy

To create a policy:

  1. From the Harness FME navigation menu, click on Project, Account, or Organization Settings.

  2. Under Security and Governance, select Policies. This directs you to the Overview tab which displays overall policy health over a selected time range.

  3. Navigate to the Policies tab and click + New Policy. Optionally, you can import a policy from Git by clicking the dropdown menu and selecting Import from Git.

  4. Enter a name for the policy and select the setup option:

    • Inline to author the policy in the Harness editor.
    • Remote to reference a Rego policy stored in a Git repository. Select a connector, repository, branch, and Rego path, then click Apply.
  5. This opens the Policy Editor view, where you can author your own policy or use an out-of-the-box sample.

    Policy editor view

    The editor includes a code editor for writing or modifying Rego, a Testing Terminal tab to validate policy behavior, and a Library tab containing sample policies.

    FME policy library tab with sample policies

    • In the policy editor, write or paste your Rego logic.
    • Use the Testing Terminal to test the policy against sample inputs.
    • Click Save.
  6. Test the policy by opening the Testing Terminal tab.

  7. Click Select Input.

  8. Choose the appropriate inputs, including the entity type, organization, project, and action (On Save). Then, select an entity from the list of results.

    Select input for policy testing

  9. Click Apply, then click Test. Review the output to confirm the policy behaves as expected.

  10. Click Next: Enforce Policy.

  11. Configure the following enforcement settings:

    • Scope: Select the appropriate scope, for example: Account.

    • Trigger event: Select On Save.

    • Severity:

      • Warn and Continue: Violations generate a warning, but the entity is saved.
      • Error and Exit: Violations block the save operation.
  12. Click You're all set! to save and enforce the policy.

Policies do not apply retroactively

Existing FME entities are not automatically evaluated against new policies. A policy runs only when a feature flag or feature flag definition is created, updated, deleted, or archived. To evaluate an existing entity, save it again.

Add the policy to a policy set

Once you've created an individual policy, you must add it to a policy set before you can apply it to your feature flags. Policy sets allow you to group policies and configure where they will be enforced.

To add a policy set:

  1. Navigate to the Policy Sets tab.

  2. Click + New Policy Set.

  3. In the Overview section, enter a name and optionally, include a description.

  4. Select the entity type that this policy set applies to: Feature Flag, Feature Flag Definition, FME Environment, FME Segment, or FME Segment Definition.

  5. Select On Save as the trigger event.

  6. Click Continue.

    New policy set configuration

  7. In the Policy evaluation criteria section, click + Add Policy.

  8. Select a policy applicable to the chosen entity type (feature flag, environment, or segment).

    Add policy to a policy set

  9. To the right of the policy, select Warn and Continue or Error and Exit.

    • Warn and Continue: If a policy isn't met when an entity is evaluated, you receive a warning but the entity is saved.
    • Error and Exit: If a policy isn't met when an entity is evaluated, you receive an error and the entity is not saved.
  10. Click Apply.

  11. To add an additional policy, click + Add Policy. When you're done adding policies to a policy set, click Finish.

    Policy set with policies added

  12. In the Policy Sets list, click the Enforced checkbox for the policy set you created.

    Enforced checkbox for policy set

How policies are evaluated

Policies are evaluated whenever a Feature Flag, Feature Flag Definition, FME Environment, FME Segment, or FME Segment Definition entity is created, updated, deleted, or archived. The input payload sent to OPA includes an entityMetadata.changeTrigger field (create, update, delete, or archive) so you can write policies that apply to specific change types.

An FME Feature Flag policy is evaluated when you change a feature flag's metadata. Examples of changes that trigger evaluation:

  • Creating a new feature flag
  • Updating a flag's name, description, tags, or metrics
  • Archiving or deleting a feature flag

On success, the change is applied. On failure, the result depends on the severity you configured:

  • Warn and Continue: The change is applied, but you receive a warning message.
  • Error and Exit: The change is blocked, and you receive an error message.
Use changeTrigger to scope your policies

The entityMetadata.changeTrigger field in the input payload lets you target specific operations. For example, you might skip name convention checks on delete to avoid blocking cleanup of legacy flags. See the example policy for a pattern that excludes delete operations.

Manage policy evaluations

Navigate to the Evaluations tab to view all successful, warning, and failed policy set evaluations. Use the Type dropdown menu to filter by entities, and the Action dropdown menu to filter by On Save events.

Evaluations filtered by entity type

Use the Status dropdown menu to filter evaluations by Success, Failed, or Warning. You can also use the time range selector to switch to a custom time range or a preset such as the past week, past month, or past three months.

Evaluations filtered by status

Click on an evaluation in the list to access the policy set that was evaluated. You can then click into the policy set details and see associated policies, or click into the policy definition itself.

Policy set evaluation details

From here, you can review which policies were applied and their evaluation results.

See also