Skip to content

rego: Platform rules support#2792

Open
micromaomao wants to merge 9 commits into
microsoft:mainfrom
micromaomao:platform-rules-mainrebase
Open

rego: Platform rules support#2792
micromaomao wants to merge 9 commits into
microsoft:mainfrom
micromaomao:platform-rules-mainrebase

Conversation

@micromaomao

@micromaomao micromaomao commented Jun 25, 2026

Copy link
Copy Markdown
Member

This PR implements the platform_rules object, which can define environment variables and mounts that are allowed to be added to any container, without having to include them again in the container definitions. This allows us to have fragments that are "platform independent", because these fragments would not need to include the rules for platform specific env and mounts, and potentially other container fields in the future.

Example platform_rules definition:

platform_rules := [
  {
    "env_rules": [
      {
        "name": "(?i)(FABRIC)_.+",
        "name_strategy": "re2",
        "value": ".+",
        "value_strategy": "re2"
      }
    ],
    "mounts": [
      {
        "destination": "/var/run/secrets/kubernetes.io/serviceaccount",
        "options": [
          "rbind",
          "rshared",
          "ro"
        ],
        "source": "sandbox:///tmp/atlas/emptydir/.+",
        "type": "bind"
      }
    ]
  }
]

This can be part of the main policy, or can be put in a fragment. If this is in a fragment, it will only be imported if the includes field contains "platform_rules", e.g.:

fragments := [
  {
    "feed": "mcr.microsoft.com/aci/aci-cc-infra-fragment",
    "includes": [
      "containers",
      "fragments",
      "platform_rules"
    ],
    "issuer": "did:x509:0:sha256:cjKyji1crjt6AGHVTkOmjXaZuI1d0rBB1kU8OgqRXfs::subject:CN:skr",
    "minimum_svn": "4"
  }
]

If multiple platform rules are defined, a container matching any one of them can be started.

platform_rules is introduced in framework version 0.5.0. Policies/fragments with an older framework_version that happen to contain a platform_rules field will have it silently ignored (in case the name is reused for something else).

This PR ports over some commits from #2789. Review just the new changes

Also, fix the following:

  • unable to start container with empty env list when non-required rules present
  • create_container enforcement denial message missing the input.rule field.

…ching strategies

This is to make it easier to parameterize environment rules.

Currently, name and value for an environment rule are actually combined into one
"pattern" field, and there is only one strategy for the combined pattern.  This
presents a problem when a fragment wants to delegate the decision of e.g.
whether to match the value (but only the value, not the key) with a regex or
with a fixed string.  We split "pattern" and "strategy" out into "name",
"name_strategy", "value" and "value_strategy" in order to allow more flexibility
when fragment exposes env-var parameters.

Signed-off-by: Tingmao Wang <tingmaowang@microsoft.com>
Signed-off-by: Tingmao Wang <tingmaowang@microsoft.com>
Signed-off-by: Tingmao Wang <tingmaowang@microsoft.com>
…ired rules present

This refactors rule_ok (and renames it) to fix the `some env in envList` being
applied at the wrong level.

Signed-off-by: Tingmao Wang <tingmaowang@microsoft.com>
Signed-off-by: Tingmao Wang <tingmaowang@microsoft.com>
This currently support containers[_].env_rules and containers[_].mounts.  If
multiple platform_rules are defined, a container matching either one can be
started (but in a consistent manner - e.g. if two platforms have different
environment variables or mounts, a container can't "mix and match" between
them).

In order to achieve the above consistency, we "patch" the container objects
instead of adding logic to e.g. env_rule_ok or envList_ok.  This also means that
the error_objects of a denial message will reflect the platform rules inserted.

Signed-off-by: Tingmao Wang <tingmaowang@microsoft.com>
…e field

Currently we only add input.rule to the original input, not the redacted input.
This results in the case of create_container not having the "rule" field in the
final deny message, but other enforcement points do have it since in those cases
the redactSensitiveData return the original input map.

Signed-off-by: Tingmao Wang <tingmaowang@microsoft.com>
Signed-off-by: Tingmao Wang <tingmaowang@microsoft.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR bumps the security policy framework version and extends the Rego framework to support platform_rules, allowing platform-specific env/mount allowances to be applied across containers (including those sourced from fragments). It also updates env rule matching to support a split name/value form, fixes an enforcement decision payload omission (input.rule), and expands the rego test suite with new platform-rules scenarios.

Changes:

  • Bump framework version to 0.5.0 and update Rego framework logic to apply platform_rules when building candidate containers.
  • Extend env rule evaluation to support both "pattern"/"strategy" and "name"/"value" rule forms; fix required/non-required env rule evaluation for empty env lists.
  • Add/adjust tests and embedded Rego policy fixtures to validate platform rules across policy/fragments and error payload behavior.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
pkg/securitypolicy/version_framework Updates embedded framework version to 0.5.0.
pkg/securitypolicy/securitypolicyenforcer_rego.go Ensures input.rule is present in denial decision input prior to redaction/serialization.
pkg/securitypolicy/securitypolicy.go Extends EnvRuleConfig with fields to support split name/value env rule form.
pkg/securitypolicy/securitypolicy_marshal.go Marshals env rules in either legacy pattern form or new name/value form.
pkg/securitypolicy/framework.rego Adds platform rules plumbing and applies them to candidate containers; refactors env rule matching.
pkg/securitypolicy/regopolicy_linux_test.go Updates env tests and adds platform rules test coverage + embeds fixture policies.
pkg/securitypolicy/rego_utils_test.go Adjusts random env generation and refactors fragment container setup helper used by tests.
pkg/securitypolicy/policy_with_platform_rules.rego Adds an embedded test policy that includes platform_rules.
pkg/securitypolicy/fragment_test_policies/platform_rules.rego Adds an embedded fragment fixture exporting platform_rules.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +111 to +117
// If UseNameValue is true, the marshalled Rego will use rules with name and
// value separately, and ignore .Rule and .Strategy.
UseNameValue bool
Name string
NameStrategy EnvVarRule
Value string
ValueStrategy EnvVarRule
}

env_ok(pattern, "string", value) {
# A env rule can be of two form:
Comment on lines +1246 to +1247
anyKeyInConstraints := strings.Split(envList[0], "=")[0]
return assertDecisionJSONContains(t, err, "invalid env list", anyKeyInConstraints)
@micromaomao micromaomao requested a review from takuro-sato June 25, 2026 13:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants