Skip to content

Partial Evaluation return known values filter #7997

@huntkalio

Description

@huntkalio

https://github.com/orgs/open-policy-agent/discussions/722#discussioncomment-14812556

Short description

When known values and unknown values at the same level,the Partial Evaluation will return filter include known values
opa version:

Version: 1.9.0
Build Commit: c49e670294e45bb3fd76b9e945cf821478a4bbfc
Build Timestamp: 2025-09-26T08:53:51Z
Build Hostname: 
Go Version: go1.25.1
Platform: linux/amd64
Rego Version: v1
WebAssembly: unavailable

Steps To Reproduce

data

{
        "authz": {
                "rbac_roles": {
                        "KafkaFullAccessRole": {
                                "resources": [{
                                        "type": "kafka*",
                                        "name": "*ab*"
                                }],
                                "permissions": ["list", "get", "create", "update", "delete"]
                        }
                },
                "rbac_users": {
                        "test": ["KafkaFullAccessRole"]
                }
        }
}

inut

{
        "input": {
                "userInfo": {
                        "username": "test"
                },
                "operation": "get",
                "resource": {
                        "type": "kafka"
                }
        },
        "unknowns": ["input.resource.name"]
}
package kafka.authz_filter

import data.authz
import rego.v1

default allow := false

allow if {
	rbac_allow
}

current_user := input.userInfo.username
current_groups := input.userInfo.groups
current_operation := input.operation

matches(pat, x) if {
    # constant
    not contains(pat, "*")
    pat == x
}

matches(pat, x) if {
    # *
    pat == "*"
}

matches(pat, x) if {
	 # abc*
	endswith(pat, "*")
	not startswith(pat, "*")
	startswith(x, substring(pat, 0, count(pat)-1))
}

matches(pat, x) if {
	 # *def
	startswith(pat, "*")
	not endswith(pat, "*")
	endswith(x, substring(pat, 1,count(pat)-1))
}

matches(pat, x) if {
	# *hij*
	count(pat) > 1
	startswith(pat, "*")
	endswith(pat, "*")
	contains(x, substring(pat, 1, count(pat)-2))
}

resource_matches(resource_pattern, request_resource) if {
	matches(resource_pattern.type, request_resource.type)
	matches(resource_pattern.name, request_resource.name)
}

rbac_allow if {
	user_roles := authz.rbac_users[current_user]
	some role_name in user_roles
	role_grants_access(role_name)
}

role_grants_access(role_name) if {
	role := authz.rbac_roles[role_name]
	current_operation in role.permissions
	some resource_pattern in role.resources
	resource_matches(resource_pattern, input.resource)
}

decision := {"allow": allow}
curl localhost:8181/v1/compile/kafka/authz_filter/allow -H "Accept: application/vnd.opa.sql.mysql+json"  -d @test/unknownshttpinput.json 
{"result":{"query":"WHERE (resource.type LIKE 'kafka%' AND resource.name LIKE '%ab%')"}}

why sql have 'resource.type LIKE 'kafka%' ' condition, it's not unknowns

Expected behavior

sql don't have 'resource.type LIKE 'kafka%' ' condition,

Additional context

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions