Skip to content

Commit 4e787a1

Browse files
committed
Restructure Policy into per-repository restrictions and overrides
Replace the ordered Rule list with a repeated RepositoryPolicy, one entry per repository the policy constrains (in practice "hexpm" and the org's own repository). Each entry has: * restriction — baseline advisory_min_severity / retirement_reasons / cooldown limits applied to every release in the repository * overrides — per-package ALLOW/DENY with an optional requirement For each candidate release the client matches the entry for its repository, then evaluates overrides (most specific requirement wins; ALLOW bypasses the restriction, DENY blocks), then the restriction. An ALLOW override is exempt from the restriction; everything else in the repository is subject to it. The Filter, Rule, oneof action, and Availability messages are gone. Restriction imports package.proto and types advisory_min_severity and retirement_reasons as the AdvisorySeverity and RetirementReason enums rather than bare uint32, so the values are symbolic. This is wire-identical to uint32 (proto2 enums encode as varints) and still decodes unknown future values as integers. visibility is unchanged. Regenerate hex_pb_policy.erl and update the policy test fixtures.
1 parent ed77bf1 commit 4e787a1

5 files changed

Lines changed: 2119 additions & 177 deletions

File tree

proto/hex_pb_policy.proto

Lines changed: 61 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
syntax = "proto2";
22

3+
import "hex_pb_package.proto";
4+
35
message Policy {
46
// Name of repository
57
required string repository = 1;
@@ -17,26 +19,69 @@ message Policy {
1719
// treat unknown values as PRIVATE per the fail-closed rule.
1820
required Visibility visibility = 4;
1921

20-
// Categorical advisory rule. If set, deny any release whose maximum
21-
// advisory severity is at least this value. Values map to AdvisorySeverity
22-
// in package.proto (SEVERITY_NONE..SEVERITY_CRITICAL = 0..4).
23-
// Unset = rule disabled.
24-
optional uint32 advisory_min_severity = 5;
25-
26-
// Categorical retirement rule. If non-empty, deny any release retired with
27-
// a reason in this set. Values map to RetirementReason in package.proto
28-
// (RETIRED_OTHER..RETIRED_RENAMED = 0..4). Empty = rule disabled.
29-
repeated uint32 retirement_reasons = 6 [packed=true];
30-
31-
// Optional minimum release age for every package version governed by this
32-
// policy. Same duration grammar as the Hex cooldown config ("7d", "2w",
33-
// "1mo", "0"). Unset or "0" means no policy cooldown. If multiple active
34-
// policies declare cooldowns, the effective cooldown is the strictest one.
35-
optional string cooldown = 7;
22+
// One entry per repository the policy constrains (in practice "hexpm" and
23+
// the org's own repository). A candidate release is matched to the entry
24+
// whose repository equals the release's repository; a release from a
25+
// repository with no matching entry is unconstrained by this policy.
26+
repeated RepositoryPolicy repositories = 5;
3627
}
3728

3829
enum Visibility {
3930
// PRIVATE is the safe default; unknown enum values must be treated as PRIVATE.
4031
VISIBILITY_PRIVATE = 0;
4132
VISIBILITY_PUBLIC = 1;
4233
}
34+
35+
message RepositoryPolicy {
36+
// Repository this entry applies to (e.g. "hexpm" or the org's repository).
37+
required string repository = 1;
38+
39+
// Baseline limits applied to every release in this repository. Unset = no
40+
// restriction. Restrictions never apply to releases permitted by an ALLOW
41+
// override (those bypass all limits).
42+
optional Restriction restriction = 2;
43+
44+
// Per-package final say, evaluated against each release in this repository.
45+
// An ALLOW override permits the release immediately and bypasses
46+
// `restriction`; a DENY override blocks it. When multiple overrides match a
47+
// release, the one with the most specific requirement wins.
48+
repeated Override overrides = 3;
49+
}
50+
51+
message Restriction {
52+
// Advisory limit. If set, deny any release whose maximum advisory severity
53+
// is at least this value. Unset = no advisory limit.
54+
optional AdvisorySeverity advisory_min_severity = 1;
55+
56+
// Retirement limit. If non-empty, deny any release retired with a reason in
57+
// this set. Empty = no retirement limit.
58+
repeated RetirementReason retirement_reasons = 2 [packed=true];
59+
60+
// Minimum release age. Same duration grammar as the Hex cooldown config
61+
// ("7d", "2w", "1mo", "0"). Unset or "0" = no minimum age. If multiple
62+
// active policies declare cooldowns, the effective cooldown is the strictest.
63+
optional string cooldown = 3;
64+
}
65+
66+
message PackageRef {
67+
// Package name.
68+
required string package = 1;
69+
70+
// Optional version requirement (e.g. "~> 1.7"). Unset = the whole package.
71+
optional string requirement = 2;
72+
}
73+
74+
message Override {
75+
// Whether this override permits or blocks the matching release.
76+
required OverrideAction action = 1;
77+
78+
// The package (and optional requirement) the override applies to.
79+
required PackageRef ref = 2;
80+
}
81+
82+
enum OverrideAction {
83+
// Permit the release and bypass `restriction`.
84+
OVERRIDE_ACTION_ALLOW = 0;
85+
// Block the release.
86+
OVERRIDE_ACTION_DENY = 1;
87+
}

0 commit comments

Comments
 (0)