Skip to content
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

Bulk acl message fixup oss #12470

Merged
merged 17 commits into from
Mar 11, 2022
Merged

Bulk acl message fixup oss #12470

merged 17 commits into from
Mar 11, 2022

Conversation

markan
Copy link
Contributor

@markan markan commented Mar 1, 2022

This does a bulk conversion for improved Permission Denied errors.

Part of issue #12240

The intent is to incrementally move us towards higher resolution errors. While this is a relatively large PR. This can be read by individual commit, which should hopefully be relatively digestible. I've tried to split commits so semantic changes and mechanical changes are done separately in the hope that it will be easier to review.

There are a few areas we will need to pick up in later issues

  • Capturing identity information #12481
  • Reworking ResolveResult and AllowAuthorizer into one structure, and working the final product all the way through the system. This probably involves moving more stuff into acl to simplify things. This may be one as part of the capture of identity information #11337
  • reworking the catalog information to return errors #12241
  • thinking about how to give better hints on filters.
  • Cleaning up some of places where we directly create PermissionDenied structs to include detailed information

@github-actions github-actions bot added theme/acls ACL and token generation theme/envoy/xds Related to Envoy support labels Mar 1, 2022
@vercel vercel bot temporarily deployed to Preview – consul-ui-staging March 1, 2022 01:15 Inactive
@vercel vercel bot temporarily deployed to Preview – consul March 1, 2022 01:15 Inactive

// ToAllowAuthorizer is needed until we can use ResolveResult in all the places this interface is used.
ToAllowAuthorizer() AllowAuthorizer
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Eventually this will be unified with the ACLResolveResult structure, but want to take that on as a separate line item. #12481

.changelog/12470.txt Outdated Show resolved Hide resolved
acl/authorizer.go Outdated Show resolved Hide resolved
// AllowAuthorizer is a wrapper to expose the *Allowed methods.
// This and the ToAllowAuthorizer function exist to tide us over until the ResolveResult struct
// is moved into acl.
type AllowAuthorizer struct {
Copy link
Member

Choose a reason for hiding this comment

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

Is the gist about this that we only ever make blah(ctx) != Allow conditionals in the code, so unify those behind a better call structure?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. That is by far the most common pattern we see.

acl/authorizer.go Outdated Show resolved Hide resolved
acl/authorizer.go Outdated Show resolved Hide resolved
acl/authorizer.go Outdated Show resolved Hide resolved
acl/authorizer.go Outdated Show resolved Hide resolved
acl/authorizer.go Outdated Show resolved Hide resolved
@@ -161,6 +162,280 @@ type Authorizer interface {

// Embedded Interface for Consul Enterprise specific ACL enforcement
enterpriseAuthorizer

// ToAllowAuthorizer is needed until we can use ResolveResult in all the places this interface is used.
ToAllowAuthorizer() AllowAuthorizer
Copy link
Member

Choose a reason for hiding this comment

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

Does this need to be a method? Do any of the implementation of this interface do more than &AllowAuthorizer{a}?

If they are all the same there may be a benefit towards just having func acl.NewAllowAuthorizer(Authorizer) instead

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a transitional method; in upcoming PRs more functionality will be loaded onto it (in particular capturing authorization source information), but eventually I'd like to move a bunch of stuff into the ACL directory and hopefully remove this entirely.

acl/errors.go Outdated Show resolved Hide resolved
acl/errors.go Outdated Show resolved Hide resolved
acl/errors.go Outdated Show resolved Hide resolved
}

// ACLReadAllowed checks for permission to list all the ACLs
func (a AllowAuthorizer) ACLReadAllowed(ctx *AuthorizerContext) error {
Copy link
Member

Choose a reason for hiding this comment

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

Followup: do these even need to be methods, or could they be a suite of package functions with a leading argument Authorizer so your in-endpoint checks would be:

if acl.ACLReadAllowed(authz, ctx) {
  ...
}

which is terser than what shows up down below.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm curious about this too; it feels like added indirection and I think RB's suggested functions read better

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The intent is to merge AllowAuthorizer and ACLResolveResult from consul/acl.go in a future PR. These would be methods on the joined class

@@ -220,6 +220,8 @@ func (h *Health) ServiceNodes(args *structs.ServiceSpecificRequest, reply *struc
// If we're doing a connect or ingress query, we need read access to the service
// we're trying to find proxies for, so check that.
if args.Connect || args.Ingress {
// TODO: ACL Error improvements; can this be improved? What happens if we returned an error here?
// Is this similar to filters where we might want to return a hint?
if authz.ServiceRead(args.ServiceName, &authzContext) != acl.Allow {
Copy link
Member

Choose a reason for hiding this comment

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

The catalog and health endpoints (and parts of agent) expect the filter style of ACL enforcement (200s instead of 403s).

@@ -464,16 +464,16 @@ func (m *Internal) KeyringOperation(
}
switch args.Operation {
case structs.KeyringList:
if authz.KeyringRead(nil) != acl.Allow {
return fmt.Errorf("Reading keyring denied by ACLs")
Copy link
Member

Choose a reason for hiding this comment

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

For the record this error message is now changing.

}
case structs.KeyringInstall:
fallthrough
case structs.KeyringUse:
fallthrough
case structs.KeyringRemove:
if authz.KeyringWrite(nil) != acl.Allow {
return fmt.Errorf("Modifying keyring denied due to ACLs")
Copy link
Member

Choose a reason for hiding this comment

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

For the record this error message is now changing.

@@ -554,57 +554,64 @@ func TestTxn_Apply_ACLDeny(t *testing.T) {
}

// Verify the transaction's return value.
var expected structs.TxnResponse
var outPos int
Copy link
Member

Choose a reason for hiding this comment

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

Can you explain the intent here please?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The broad purpose here is to perform a slightly stricter test on what we return; in particular make sure we have the right resource and permission information.

The original code attempted to build an identical result to the expected return value from the API call and directly compare them, but that seemed impractical given the new structure. So I altered this into an element by element comparison inline..

Copy link
Member

@rboyer rboyer left a comment

Choose a reason for hiding this comment

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

I left a few comments.

acl/errors.go Outdated Show resolved Hide resolved
agent/acl.go Outdated Show resolved Hide resolved
}

// ACLReadAllowed checks for permission to list all the ACLs
func (a AllowAuthorizer) ACLReadAllowed(ctx *AuthorizerContext) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm curious about this too; it feels like added indirection and I think RB's suggested functions read better

@vercel vercel bot temporarily deployed to Preview – consul-ui-staging March 9, 2022 06:37 Inactive
@vercel vercel bot temporarily deployed to Preview – consul March 9, 2022 06:37 Inactive
@markan markan force-pushed the ma/bulk-acl-message-fixup-oss branch from fe459ff to 0b02f5d Compare March 10, 2022 02:46
@vercel vercel bot temporarily deployed to Preview – consul-ui-staging March 10, 2022 05:26 Inactive
@markan markan force-pushed the ma/bulk-acl-message-fixup-oss branch from 3487780 to 4319d80 Compare March 10, 2022 06:29
@vercel vercel bot temporarily deployed to Preview – consul March 10, 2022 06:29 Inactive
@vercel vercel bot temporarily deployed to Preview – consul-ui-staging March 10, 2022 06:29 Inactive
markan added 17 commits March 9, 2022 22:53
Signed-off-by: Mark Anderson <manderson@hashicorp.com>
Signed-off-by: Mark Anderson <manderson@hashicorp.com>
Signed-off-by: Mark Anderson <manderson@hashicorp.com>
Signed-off-by: Mark Anderson <manderson@hashicorp.com>
Signed-off-by: Mark Anderson <manderson@hashicorp.com>
Signed-off-by: Mark Anderson <manderson@hashicorp.com>
Signed-off-by: Mark Anderson <manderson@hashicorp.com>
Signed-off-by: Mark Anderson <manderson@hashicorp.com>
Signed-off-by: Mark Anderson <manderson@hashicorp.com>
Signed-off-by: Mark Anderson <manderson@hashicorp.com>
Signed-off-by: Mark Anderson <manderson@hashicorp.com>
Signed-off-by: Mark Anderson <manderson@hashicorp.com>
Signed-off-by: Mark Anderson <manderson@hashicorp.com>
Signed-off-by: Mark Anderson <manderson@hashicorp.com>
Signed-off-by: Mark Anderson <manderson@hashicorp.com>
Signed-off-by: Mark Anderson <manderson@hashicorp.com>
Signed-off-by: Mark Anderson <manderson@hashicorp.com>
@markan markan force-pushed the ma/bulk-acl-message-fixup-oss branch from 4319d80 to 40ef780 Compare March 10, 2022 06:54
@vercel vercel bot temporarily deployed to Preview – consul March 10, 2022 06:54 Inactive
@vercel vercel bot temporarily deployed to Preview – consul-ui-staging March 10, 2022 06:54 Inactive
@kisunji kisunji self-requested a review March 10, 2022 19:38
@markan markan merged commit aaefe15 into main Mar 11, 2022
@markan markan deleted the ma/bulk-acl-message-fixup-oss branch March 11, 2022 02:48
@hc-github-team-consul-core
Copy link
Collaborator

🍒 If backport labels were added before merging, cherry-picking will start automatically.

To retroactively trigger a backport after merging, add backport labels and re-run https://circleci.com/gh/hashicorp/consul/605613.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
theme/acls ACL and token generation theme/envoy/xds Related to Envoy support
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Go through permission checks and rework to generated detailed information.
4 participants