Introduce expiration field for accessConfig policies#4036
Introduce expiration field for accessConfig policies#4036matheuscscp wants to merge 1 commit intoproject-zot:mainfrom
accessConfig policies#4036Conversation
Signed-off-by: Matheus Pimenta <matheuscscp@gmail.com>
accessConfig policies
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4036 +/- ##
=======================================
Coverage 91.54% 91.55%
=======================================
Files 197 197
Lines 28395 28406 +11
=======================================
+ Hits 25995 26007 +12
+ Misses 1549 1547 -2
- Partials 851 852 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
This PR adds an optional expiration timestamp to accessControl policy entries (server-side accessConfig), allowing policy rules to become inactive after a configured time without requiring license/token re-issuance.
Changes:
- Add
ExpiresAt *time.Timetoconfig.Policyand enforce expiry during authorization evaluation. - Extend server config loading to decode RFC3339 timestamps from config files.
- Add tests for config decoding of
expiresAtand for authz behavior with expired/non-expired policies.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/cli/server/root.go | Adds RFC3339 string-to-time decoding hook for config unmarshalling. |
| pkg/cli/server/root_test.go | Adds coverage ensuring expiresAt decodes and malformed values fail config load. |
| pkg/api/config/config.go | Introduces Policy.ExpiresAt as an optional expiration timestamp. |
| pkg/api/authz.go | Skips expired policy entries during permission checks and glob pattern generation. |
| pkg/api/authz_internal_test.go | Adds unit tests covering expiry behavior for user/group policies and glob patterns. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| // ExpiresAt is an optional expiration time for this policy entry. | ||
| // When set, the policy is ignored once the timestamp is in the past. | ||
| ExpiresAt *time.Time |
| // isPolicyExpired reports whether a policy's optional ExpiresAt has passed. | ||
| func isPolicyExpired(p config.Policy) bool { | ||
| return p.ExpiresAt != nil && p.ExpiresAt.Before(time.Now()) | ||
| } |
| cfg := config.New() | ||
|
|
||
| err := cli.LoadConfiguration(cfg, tmpfile) | ||
| So(err, ShouldNotBeNil) |
|
@rchincha @andaaron Ramkumar told me in Slack that you were debating internally if this feature makes sense to be in Zot at all from a separation of concerns perspective. I think it does, as it is a simple and common access control feature, all the major cloud providers have it, please see the updated PR description. |
|
Superseded by: #4040 |
Use case
Similar to #3755 (implemented via #3761), but now for the
accessConfigpolicies. It turns out that issuing customer licenses as simple "ID cards" i.e. without the permissions embedded directly on them is much better (i.e. use OIDC federation), because we don't have to re-issue a license for a customer every time their permissions change. This feature allows us to configure the customer access on the server side via static Zot config (e.g. giving a customer limited access to a container image as a free trial, for example), and they can always use the same license, which is now just an attestation of their identity.Why this feature belongs in Zot from a separation of concerns perspective
This is an important feature for OIDC federation users: OIDC's responsibility is to simply identify a user/identity (authn), and the relying party (Zot) is fully responsible for authz. When OIDC federation was introduced (via #3711), we agreed that it would entirely rely on
accessConfig. So to implement a rule like this for OIDC, the only system that can do it is Zot, the relying party. There's nowhere else where this rule can be enforced from OIDC perspective. So the separation of concerns is:Furthermore, a feature like this for access control is very common and it would simply enrich Zot's capabilities. All the three major cloud providers have this feature, see below.
AWS:
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_aws-dates.html
{ "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "service-prefix:action-name", "Resource": "*", "Condition": { "DateGreaterThan": {"aws:CurrentTime": "2020-04-01T00:00:00Z"}, "DateLessThan": {"aws:CurrentTime": "2020-06-30T23:59:59Z"} } } ] }GCP:
https://docs.cloud.google.com/iam/docs/conditions-overview#example-date-time
Azure:
https://learn.microsoft.com/en-us/azure/role-based-access-control/pim-integration
{ "properties": { "principalId": "aaaaaaaa-bbbb-cccc-1111-222222222222", "roleDefinitionId": "/subscriptions/.../providers/Microsoft.Authorization/roleDefinitions/c8d4ff99-41c3-41a8-9f60-21dfdad59608", "requestType": "AdminAssign", "scheduleInfo": { "startDateTime": "2020-04-01T00:00:00Z", "expiration": { "type": "AfterDateTime", "endDateTime": "2020-06-30T23:59:59Z" } } } }