RoleBasedResourcePolicyResolver
A configuration-backed ResourcePolicyResolver that resolves static, role-based masking rules.
This is Ihawu's batteries-included resolver: the default, no-external-dependency way to drive masking without standing up an external engine (OPA, Casbin, ...). Rules are supplied up front as a list of ResourcePolicy entries mapping resource -> role -> field policies; resolution is a pure lookup against the principal's roles. Ihawu stays a Policy Enforcement Point — the configuration is the pre-resolved policy, and no conditions are evaluated here.
Resolution semantics:
Union across roles — the field policies of every role the principal holds are combined.
Most-restrictive-wins — when two roles mask the same field, the stricter org.ihawu.core.masking.MaskingStrategy is kept (e.g.
HIDEoutranksREDACT).Deterministic — ties between equal strategies are broken by role-name order, so the result never depends on Set iteration order.
Fail-open on absence — an unknown resource, a role with no configured policy, or a principal with no roles yields an empty list; the caller decides default visibility.
Rules are supplied directly as a List of ResourcePolicy. To load them from JSON configuration instead, use JacksonPolicyConfig.fromJson in the ihawu-jackson module.
Parameters
The static resource -> role -> field policies rules to resolve against.
See also
Samples
// Static rules: for the "employee" resource, the MANAGER role redacts salary.
val rules =
listOf(
ResourcePolicy(
resourceName = "employee",
roleFieldPolicies =
mapOf(
"MANAGER" to listOf(FieldPolicy("salary", MaskingStrategy.REDACT, placeholder = "***")),
),
),
)
val resolver = RoleBasedResourcePolicyResolver(rules)
val principal = IhawuPrincipal("u1", roles = setOf("MANAGER"), attributes = emptyMap())
val policies = resolver.resolve(principal, "employee")
check(policies == listOf(FieldPolicy("salary", MaskingStrategy.REDACT, "***")))// The principal holds two roles that mask the same field; HIDE outranks REDACT.
val rules =
listOf(
ResourcePolicy(
resourceName = "employee",
roleFieldPolicies =
mapOf(
"MANAGER" to listOf(FieldPolicy("salary", MaskingStrategy.REDACT, placeholder = "***")),
"AUDITOR" to listOf(FieldPolicy("salary", MaskingStrategy.HIDE)),
),
),
)
val resolver = RoleBasedResourcePolicyResolver(rules)
val principal = IhawuPrincipal("u1", roles = setOf("MANAGER", "AUDITOR"), attributes = emptyMap())
val policies = resolver.resolve(principal, "employee")
check(policies == listOf(FieldPolicy("salary", MaskingStrategy.HIDE)))