Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions policy/diamond/policy/tiled/tiled.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package diamond.policy.tiled

import data.diamond.policy.session.access_session

Check failure on line 3 in policy/diamond/policy/tiled/tiled.rego

View workflow job for this annotation

GitHub Actions / policy_lint / lint

Prefer importing packages over rules. To learn more, see: https://www.openpolicyagent.org/projects/regal/rules/imports/prefer-package-imports
import data.diamond.policy.token

read_scopes := {
"read:metadata",
"read:data",
}

write_scopes := {
"write:metadata",
"write:data",
"create",
"register",
}

scopes_for(claims) := read_scopes | write_scopes if {
"azp" in object.keys(claims)
endswith(claims.azp, "-blueapi")
Copy link
Contributor

Choose a reason for hiding this comment

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

What is azp?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

"authorizing party"- the client-id that the token was minted for- i.e. this token has been one that a blueapi instance has set as headers to a request to tiled, not one that has been set in a tiled browser client or tiled login flow.

This of course then only works if your request originated with blueapi, meaning as soon as there's an experiment UI in front of that request it stops working. When we make use of token-exchange flow in keycloak from the incoming request token, I think we can request from keycloak a token with "aud": ["blueapi", "tiled"] and check that both audiences are present, then configure our services to never give both audiences otherwise? Or make use of some optional scope for the blueapi client - I can't see many other ways of checking that the request has come from a blueapi instance (which should be the only thing permitted to write to tiled) without checking something about the party sending the token.

https://www.keycloak.org/securing-apps/token-exchange

}

scopes_for(claims) := read_scopes if {
"azp" in object.keys(claims)
not endswith(claims.azp, "-blueapi")
}

scopes_for(claims) := read_scopes if {
not "azp" in object.keys(claims)
}
Comment on lines +23 to +30
Copy link
Contributor

Choose a reason for hiding this comment

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

I think these can be combined?

Suggested change
scopes_for(claims) := read_scopes if {
"azp" in object.keys(claims)
not endswith(claims.azp, "-blueapi")
}
scopes_for(claims) := read_scopes if {
not "azp" in object.keys(claims)
}
scopes_for(claims) := read_scopes if {
not "azp" in object.keys(claims)
not endswith(claims.azp, "-blueapi")
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

  tiled_test.rego:12       | | Fail data.diamond.policy.tiled.scopes = data.diamond.policy.tiled.read_scopes with data.diamond.policy.token.claims as {}  

Looks like it fails the tests when "azp" not in token.claims? Presumably the first line is true, then it checks the second line and it isn't defined, so it returns no scopes?

There is already a token if we have made it here, it just doesn't have the azp claim- I believe it is optional, so an authenticated user could have make a request without it (I think right now we're only getting it because our audience is always account rather than <client-id>.


default scopes := set()

scopes := scopes_for(token.claims)

user_sessions contains user_session if {
some session in data.diamond.data.sessions
access_session(token.claims.fedid, session.proposal_number, session.visit_number)
user_session := sprintf("%s", [session])
}
129 changes: 129 additions & 0 deletions policy/diamond/policy/tiled/tiled_test.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package diamond.policy.tiled_test

import data.diamond.policy.tiled
import data.diamond.policy.token
import rego.v1

test_default_no_scopes if {
tiled.scopes == set()
}

test_wrong_azp_read_scopes if {
tiled.scopes == tiled.read_scopes with token.claims as {}
tiled.scopes == tiled.read_scopes with token.claims as {"sub": "foo"}
tiled.scopes == tiled.read_scopes with token.claims as {"azp": "foo"}
}

test_blueapi_given_write_scopes if {
tiled.scopes == {
"read:metadata",
"read:data",
"write:metadata",
"write:data",
"create",
"register",
} with token.claims as {"azp": "foo-blueapi"}
}

diamond_data := {
"subjects": {
"alice": {
"permissions": [],
"proposals": [1],
"sessions": [],
},
"bob": {
"permissions": ["b07_admin"],
"proposals": [],
"sessions": [11],
},
"carol": {
"permissions": ["super_admin"],
"proposals": [],
"sessions": [],
},
"desmond": {
"permissions": [],
"proposals": [2],
"sessions": [13],
},
"edna": {
"permissions": [],
"proposals": [2],
"sessions": [13, 14],
},
"oscar": {
"permissions": [],
"proposals": [],
"sessions": [],
},
},
"sessions": {
"11": {
"beamline": "i03",
"proposal_number": 1,
"visit_number": 1,
},
"12": {
"beamline": "b07",
"proposal_number": 1,
"visit_number": 2,
},
"13": {
"beamline": "b07",
"proposal_number": 2,
"visit_number": 1,
},
"14": {
"beamline": "b07",
"proposal_number": 2,
"visit_number": 2,
},
},
"proposals": {
"1": {"sessions": {
"1": 11,
"2": 12,
}},
"2": {"sessions": {
"1": 13,
"2": 14,
}},
},
"beamlines": {"i03": {"sessions": [11]}, "b07": {"sessions": [12, 13, 14]}},
"admin": {"b07_admin": ["b07"]},
}

test_user_session_tags if {
tiled.user_sessions == set() with data.diamond.data as diamond_data
with data.diamond.policy.token.claims as {"fedid": "oscar"}

Check failure on line 99 in policy/diamond/policy/tiled/tiled_test.rego

View workflow job for this annotation

GitHub Actions / policy_lint / lint

Reference ignores import of data.diamond.policy.token. To learn more, see: https://www.openpolicyagent.org/projects/regal/rules/imports/ignored-import
tiled.user_sessions == {
"{\"beamline\": \"b07\", \"proposal_number\": 1, \"visit_number\": 2}",
"{\"beamline\": \"i03\", \"proposal_number\": 1, \"visit_number\": 1}",
} with data.diamond.data as diamond_data
with data.diamond.policy.token.claims as {"fedid": "alice"}

Check failure on line 104 in policy/diamond/policy/tiled/tiled_test.rego

View workflow job for this annotation

GitHub Actions / policy_lint / lint

Reference ignores import of data.diamond.policy.token. To learn more, see: https://www.openpolicyagent.org/projects/regal/rules/imports/ignored-import
tiled.user_sessions == {
"{\"beamline\": \"b07\", \"proposal_number\": 1, \"visit_number\": 2}",
"{\"beamline\": \"i03\", \"proposal_number\": 1, \"visit_number\": 1}",
"{\"beamline\": \"b07\", \"proposal_number\": 2, \"visit_number\": 1}",
"{\"beamline\": \"b07\", \"proposal_number\": 2, \"visit_number\": 2}",
} with data.diamond.data as diamond_data
with data.diamond.policy.token.claims as {"fedid": "bob"}

Check failure on line 111 in policy/diamond/policy/tiled/tiled_test.rego

View workflow job for this annotation

GitHub Actions / policy_lint / lint

Reference ignores import of data.diamond.policy.token. To learn more, see: https://www.openpolicyagent.org/projects/regal/rules/imports/ignored-import
tiled.user_sessions == {
"{\"beamline\": \"b07\", \"proposal_number\": 1, \"visit_number\": 2}",
"{\"beamline\": \"i03\", \"proposal_number\": 1, \"visit_number\": 1}",
"{\"beamline\": \"b07\", \"proposal_number\": 2, \"visit_number\": 1}",
"{\"beamline\": \"b07\", \"proposal_number\": 2, \"visit_number\": 2}",
} with data.diamond.data as diamond_data
with data.diamond.policy.token.claims as {"fedid": "carol"}

Check failure on line 118 in policy/diamond/policy/tiled/tiled_test.rego

View workflow job for this annotation

GitHub Actions / policy_lint / lint

Reference ignores import of data.diamond.policy.token. To learn more, see: https://www.openpolicyagent.org/projects/regal/rules/imports/ignored-import
tiled.user_sessions == {
"{\"beamline\": \"b07\", \"proposal_number\": 2, \"visit_number\": 1}",
"{\"beamline\": \"b07\", \"proposal_number\": 2, \"visit_number\": 2}",
} with data.diamond.data as diamond_data
with data.diamond.policy.token.claims as {"fedid": "desmond"}

Check failure on line 123 in policy/diamond/policy/tiled/tiled_test.rego

View workflow job for this annotation

GitHub Actions / policy_lint / lint

Reference ignores import of data.diamond.policy.token. To learn more, see: https://www.openpolicyagent.org/projects/regal/rules/imports/ignored-import
tiled.user_sessions == {
"{\"beamline\": \"b07\", \"proposal_number\": 2, \"visit_number\": 1}",
"{\"beamline\": \"b07\", \"proposal_number\": 2, \"visit_number\": 2}",
} with data.diamond.data as diamond_data
with data.diamond.policy.token.claims as {"fedid": "edna"}

Check failure on line 128 in policy/diamond/policy/tiled/tiled_test.rego

View workflow job for this annotation

GitHub Actions / policy_lint / lint

Reference ignores import of data.diamond.policy.token. To learn more, see: https://www.openpolicyagent.org/projects/regal/rules/imports/ignored-import
}
Loading