-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Add negative RBAC label matches #4253
Conversation
8dc73ba
to
c52a4ea
Compare
lib/utils/replace.go
Outdated
@@ -48,8 +48,19 @@ func ReplaceRegexp(expression string, replaceWith string, input string) (string, | |||
|
|||
// SliceMatchesRegex checks if input matches any of the expressions. The | |||
// match is always evaluated as a regex either an exact match or regexp. | |||
// | |||
// If any expression starts with "+not ", the match is negated. |
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.
Need to update the comments to reflect the updated expression.
@awly can you take a look at: https://github.com/gravitational/teleport/blob/master/lib/utils/parse/parse.go I would like us to use the "ast" approach for all function calls. As you can spot above, there is a function "email.local" that also supports variable syntax, so it will support Ping me if you want to discuss in more detail. |
@klizhentas WDYT about going all-in on https://golang.org/pkg/text/template/ instead? It looks like https://github.com/gravitational/teleport/blob/master/lib/utils/parse/parse.go just reimplements a subset of that, except for input data access ( |
c52a4ea
to
b2b5213
Compare
Chatted with @klizhentas, we can use I'll flesh that out and re-open this PR. |
After more chatting, @klizhentas convinced me to go with our custom DSL. |
b2b5213
to
9d71803
Compare
PTAL everyone, migrated this PR to use |
LGTM, I'll leave it for others to take a look. |
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.
So based on the issue example, this would be
role: {{regexp.not_match(`^critical$`)}}
@benarent almost:
|
No need to handle literal expressions (e.g. without "{{foo.bar}}" substitutions) at the higher level. Something like "foo" is a valid expression which always returns "foo" regardless of traits.
Matchers use a similar syntax to Expressions, but behave differently: - Expressions get evaluated - they interpolate some values and return a final string. - Matchers check whether some string matches a value Matchers implement the same logic as utils.SliceMatchesRegex and add 2 new functions: - {{regexp.match("foo")}} - match input against a raw regex - {{regexp.not_match("foo")}} - same as match, but inverts the result
This should be backwards-compatible plus add the {{regexp.match(...)}} and {{regexp.not_match(...)}} functions.
9d71803
to
45cf28b
Compare
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.
@awly Please take a look at my comments when you have a chance.
@@ -491,8 +491,8 @@ func (u *UserV1) Check() error { | |||
return trace.BadParameter("user name cannot be empty") | |||
} | |||
for _, login := range u.AllowedLogins { | |||
_, err := parse.RoleVariable(login) | |||
if err == nil { | |||
e, err := parse.NewExpression(login) |
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.
New logic only returns error in case of grammatic errors and accepts literal values. Doesn't it mean that now err
should return error here if it's not nil? Otherwise the following will be accepted: {{regexp_not_match(...)
which probably should not be ignored as it's a typo and we should let users know
|
||
re, err := regexp.Compile(raw) | ||
if err != nil { | ||
return nil, trace.BadParameter("failed parsing regexp %q: %v", raw, err) |
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.
May make sense to send a link to our documentation with examples. This will make our message actionable and reduce amount of support.
return nil, trace.Wrap(err) | ||
} | ||
// If this is not_match, wrap the regexpMatcher to invert | ||
// it. |
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.
Extra newline?
@klizhentas thanks for the comments, addressed in #4430 |
Also improve error output and user validation. Based on missed feedback in #4253 (review)
Also improve error output and user validation. Based on missed feedback in #4253 (review)
Normal
node_labels
matches are positive only - you must provide anexact label or a regexp that matches all valid labels.
This is problematic when you want to grant access to "any label value
except X". You could put "X" in the
deny
section of a role, but thisprevents any other roles from granting access to "X". For example, users
may have many dynamically-named environments and one "prod", and they
want to only grant access to "prod" via workflow API.
This PR adds support for
{{regexp.not_match(...)}}
function (along with{{regexp.match(...)}}
, for example{{regexp.not_match("prod")}}
.Fixes #3454