-
Notifications
You must be signed in to change notification settings - Fork 142
node: operator-enforced egress label floor (egress.require_labels) #385
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
f05932a
api: compile an egress label floor as a conjunction
HosniBelfeki f983da5
node: enforce the operator's egress label floor
HosniBelfeki fe7b1e4
docs: document the egress floor, and stop promising it without one
HosniBelfeki 881915b
node: hold the egress floor when the caller requires nothing
aojea 90112da
mobile: let the operator set the egress floor on a phone node
aojea 1b3662f
node: canonicalize the peer ID at the egress floor gate
aojea File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -575,6 +575,75 @@ func LabelCheck(required map[string]string) (biscuit.Check, error) { | |||||||||||||||||||||||||||||||||||||||
| return parser.FromStringCheck("check if " + strings.Join(clauses, " or ")) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| // LabelFloorCheck compiles an operator's egress floor (see Egress.RequireLabels) | ||||||||||||||||||||||||||||||||||||||||
| // into a single fail-closed check satisfied only when the token carries *every* | ||||||||||||||||||||||||||||||||||||||||
| // pair: `check if label("jurisdiction", "eu"), label("compliance", "gdpr")`. | ||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||
| // The conjunction is the whole difference from LabelCheck, which is a | ||||||||||||||||||||||||||||||||||||||||
| // disjunction because a caller naming several labels means "any of these will | ||||||||||||||||||||||||||||||||||||||||
| // do". A floor cannot mean that: a peer attesting only the most permissive of | ||||||||||||||||||||||||||||||||||||||||
| // several alternatives would satisfy the floor while sitting outside the | ||||||||||||||||||||||||||||||||||||||||
| // boundary the operator drew. So a floor takes a map — one value per key, no | ||||||||||||||||||||||||||||||||||||||||
| // way to spell an alternative — and requires all of it. | ||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||
| // Both are ordinary Biscuit checks, so a caller's requirement and a floor are | ||||||||||||||||||||||||||||||||||||||||
| // combined by adding each to the authorizer and letting it AND them; neither | ||||||||||||||||||||||||||||||||||||||||
| // needs to know about the other. | ||||||||||||||||||||||||||||||||||||||||
| func LabelFloorCheck(required map[string]string) (biscuit.Check, error) { | ||||||||||||||||||||||||||||||||||||||||
| if len(required) == 0 { | ||||||||||||||||||||||||||||||||||||||||
| return biscuit.Check{}, fmt.Errorf("no required labels") | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| keys := make([]string, 0, len(required)) | ||||||||||||||||||||||||||||||||||||||||
| for k := range required { | ||||||||||||||||||||||||||||||||||||||||
| keys = append(keys, k) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| sort.Strings(keys) | ||||||||||||||||||||||||||||||||||||||||
| clauses := make([]string, 0, len(required)) | ||||||||||||||||||||||||||||||||||||||||
| for _, k := range keys { | ||||||||||||||||||||||||||||||||||||||||
| if err := ValidateLabelKey(k); err != nil { | ||||||||||||||||||||||||||||||||||||||||
| return biscuit.Check{}, err | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| v := required[k] | ||||||||||||||||||||||||||||||||||||||||
| if err := ValidateLabelValue(v); err != nil { | ||||||||||||||||||||||||||||||||||||||||
| return biscuit.Check{}, err | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| clauses = append(clauses, fmt.Sprintf("%s(%q, %q)", FactLabel, k, v)) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| return parser.FromStringCheck("check if " + strings.Join(clauses, ", ")) | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| // LabelsSatisfyFloor reports whether claimed satisfies every pair of the floor. | ||||||||||||||||||||||||||||||||||||||||
| // It is the non-attested counterpart of LabelFloorCheck, for the one provider | ||||||||||||||||||||||||||||||||||||||||
| // class that has no Biscuit to check: a service local to this node, whose | ||||||||||||||||||||||||||||||||||||||||
| // labels are its own configuration and so are complete. An empty floor is | ||||||||||||||||||||||||||||||||||||||||
| // satisfied by anything, so callers may pass one unconditionally. | ||||||||||||||||||||||||||||||||||||||||
| func LabelsSatisfyFloor(floor, claimed map[string]string) bool { | ||||||||||||||||||||||||||||||||||||||||
| for k, v := range floor { | ||||||||||||||||||||||||||||||||||||||||
| if claimed[k] != v { | ||||||||||||||||||||||||||||||||||||||||
| return false | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| return true | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| // LabelsContradictFloor reports whether claimed states a *different* value for | ||||||||||||||||||||||||||||||||||||||||
| // some key the floor requires. | ||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||
| // Absence is not contradiction, which is the whole distinction from | ||||||||||||||||||||||||||||||||||||||||
| // LabelsSatisfyFloor. Gossiped claims are a discovery hint and may carry only | ||||||||||||||||||||||||||||||||||||||||
| // part of what a peer attests, so a peer silent on one pair of the floor may | ||||||||||||||||||||||||||||||||||||||||
| // still satisfy all of it in its Biscuit. Only a conflicting value is grounds | ||||||||||||||||||||||||||||||||||||||||
| // to skip such a peer before the gate has seen its attested facts; treating | ||||||||||||||||||||||||||||||||||||||||
| // silence as failure would drop providers that are inside the boundary. | ||||||||||||||||||||||||||||||||||||||||
| func LabelsContradictFloor(floor, claimed map[string]string) bool { | ||||||||||||||||||||||||||||||||||||||||
| for k, v := range floor { | ||||||||||||||||||||||||||||||||||||||||
| if got, stated := claimed[k]; stated && got != v { | ||||||||||||||||||||||||||||||||||||||||
| return true | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| return false | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+638
to
+645
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For defensive programming, explicitly handle the case where
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| // isExactService reports whether serviceStr resolves to a plain exact-match grant, as opposed to a | ||||||||||||||||||||||||||||||||||||||||
| // wildcard/prefix/suffix pattern which already collapses to a single, cheap fact via BuildServiceDatalogFact. | ||||||||||||||||||||||||||||||||||||||||
| // The classification is asked of BuildServiceDatalogFact rather than repeated here: a new wildcard shape | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For defensive programming and clarity, explicitly handle the case where
claimedisnilorflooris empty. Although map indexing on anilmap is safe in Go, explicit checks make the code more robust and self-documenting.