| id |
name |
namespace |
version |
status |
package |
allow_ttl |
actions |
owner |
caring |
| forgejo.application-access |
Forgejo authenticated application access |
forgejo:application |
v1 |
draft |
flexauth.forgejo.application |
10s |
|
railiance-apps |
| profile |
enforce |
| caring-0.4.0-rc2 |
false |
|
This source policy enforces the original three-group any-of in the sole PDP.
The registry identifies the application tenant and admitted issuer. Fresh identity
and UserInfo facts arrive only in request context from the admitted Forgejo caller,
which verifies issuer JOSE and current UserInfo before this request. They are not
static subject registry attributes. This policy requires aal2 assurance.
The PEP independently verifies the ID token and supplies fresh UserInfo groups;
the authenticated workload caller may represent only the Forgejo system. A
decision authorizes one login callback, never a later HTTP/Git/SSH/API operation.
The accompanying registry is synthetic test data, not an estate admission.
import rego.v1
default decision := {"effect": "deny", "reason": "application_access_refused"}
original_groups := {"forge-admins", "forge-coulomb-owners", "forge-coulomb-readers"}
decision := {"effect": "allow", "reason": "current_authenticated_application_access"} if {
input.action == "application.access"
object.get(input, "purpose", "") == ""
input.resource.id == "application:forgejo"
input.resource.type == "application"
input.resource.system == "forgejo"
input.tenant == input.resource.tenant
input.tenant == input.resource.attributes.tenant
input.subject.tenant == input.tenant
input.context.identity_tenant == input.tenant
input.subject.id == input.context.identity_subject
input.subject.type == input.context.identity_principal_type
input.subject.type == "human"
input.context.identity_issuer == input.resource.attributes.identity_issuer
input.context.identity_assurance == "aal2"
is_array(input.context.required_groups_any_of)
count(input.context.required_groups_any_of) == 3
{g | g := input.context.required_groups_any_of[_]} == original_groups
is_array(input.context.current_userinfo_groups)
every value in input.context.current_userinfo_groups { is_string(value) }
some group in input.context.current_userinfo_groups
group in original_groups
is_string(input.context.decisionpep_request_nonce)
count(input.context.decisionpep_request_nonce) == 64
}
package flexauth.forgejo.application_test
import rego.v1
import data.flexauth.forgejo.application
valid_request := {
"tenant": "tenant:synthetic",
"subject": {
"id": "user:synthetic",
"type": "human",
"tenant": "tenant:synthetic"
},
"action": "application.access",
"resource": {
"id": "application:forgejo",
"type": "application",
"system": "forgejo",
"tenant": "tenant:synthetic",
"attributes": {
"tenant": "tenant:synthetic",
"identity_issuer": "https://issuer.invalid"
}
},
"context": {
"identity_tenant": "tenant:synthetic",
"identity_subject": "user:synthetic",
"identity_principal_type": "human",
"identity_issuer": "https://issuer.invalid",
"identity_assurance": "aal2",
"current_userinfo_groups": [
"forge-admins"
],
"required_groups_any_of": [
"forge-admins",
"forge-coulomb-owners",
"forge-coulomb-readers"
],
"decisionpep_request_nonce": "0000000000000000000000000000000000000000000000000000000000000000"
}
}
test_original_groups_allow if {
every group in ["forge-admins", "forge-coulomb-owners", "forge-coulomb-readers"] {
application.decision.effect == "allow" with input as object.union(valid_request, {"context": object.union(valid_request.context, {"current_userinfo_groups": [group]})})
}
}
test_outsider_denied if {
application.decision.effect == "deny" with input as object.union(valid_request, {"context": object.union(valid_request.context, {"current_userinfo_groups": ["outsider"]})})
}
test_missing_identity_denied if {
application.decision.effect == "deny" with input as object.union(object.remove(valid_request, ["context"]), {"context": object.remove(valid_request.context, ["identity_issuer"])})
}
test_low_assurance_denied if {
application.decision.effect == "deny" with input as object.union(valid_request, {"context": object.union(valid_request.context, {"identity_assurance": "aal1"})})
}
test_changed_group_contract_denied if {
application.decision.effect == "deny" with input as object.union(valid_request, {"context": object.union(valid_request.context, {"required_groups_any_of": ["outsider"]})})
}
[
{
"id": "allowed-original-group",
"request": {
"tenant": "tenant:synthetic",
"subject": {
"id": "user:synthetic",
"type": "human",
"tenant": "tenant:synthetic"
},
"action": "application.access",
"resource": {
"id": "application:forgejo",
"type": "application",
"system": "forgejo",
"tenant": "tenant:synthetic",
"attributes": {
"tenant": "tenant:synthetic",
"identity_issuer": "https://issuer.invalid"
}
},
"context": {
"identity_tenant": "tenant:synthetic",
"identity_subject": "user:synthetic",
"identity_principal_type": "human",
"identity_issuer": "https://issuer.invalid",
"identity_assurance": "aal2",
"current_userinfo_groups": [
"forge-admins"
],
"required_groups_any_of": [
"forge-admins",
"forge-coulomb-owners",
"forge-coulomb-readers"
],
"decisionpep_request_nonce": "0000000000000000000000000000000000000000000000000000000000000000"
}
},
"expect": {
"effect": "allow",
"reason": "current_authenticated_application_access"
}
},
{
"id": "missing-identity-context",
"request": {
"tenant": "tenant:synthetic",
"subject": {
"id": "user:synthetic",
"type": "human",
"tenant": "tenant:synthetic"
},
"action": "application.access",
"resource": {
"id": "application:forgejo",
"type": "application",
"system": "forgejo",
"tenant": "tenant:synthetic",
"attributes": {
"tenant": "tenant:synthetic",
"identity_issuer": "https://issuer.invalid"
}
},
"context": {}
},
"expect": {
"effect": "deny",
"reason": "application_access_refused"
}
}
]