Skip to content

vttablet: improved ACL support#3649

Merged
alainjobart merged 5 commits intovitessio:masterfrom
sougou:acl
Feb 14, 2018
Merged

vttablet: improved ACL support#3649
alainjobart merged 5 commits intovitessio:masterfrom
sougou:acl

Conversation

@sougou
Copy link
Copy Markdown
Contributor

@sougou sougou commented Feb 11, 2018

This is a long overdue fix.

VTTablet was not correctly verifying ACLs for complex queries because the plan had only one 'Table' field. For queries that performed joins, vttablet would simply not perform any ACL checks. Also, subqueries were always ignored.

This change fixes all the above problems: the planbuilder builds a list of 'Permissions' which associate each referenced TableName with a Role. This is then used by QueryEngine to build a list of Authorizations (Authorized). They are all checked against the incoming request's caller id for eligibility.

We still need to upgrade the Table field in the Plan to allow for multiple tables, but that problem is now independent of the ACL feature.

vttablet was not correctly verifying ACLs for complex queries
because the plan accommodated only one table to be referenced.

- [X] Function to build the list of tables and their permissions
- [ ] Add Permissions list to planbuilder.Plan
- [ ] Use that Permissions list in QueryEngine instead of Table
- [ ] Change QueryExecutor to iterate through the list
- [ ] Remove obsolete PlanID.MinRole()
- [ ] Test
@sougou sougou changed the title vttablet: improved ACL support (WIP) vttablet: improved ACL support Feb 11, 2018
@sougou sougou requested a review from alainjobart February 11, 2018 16:51
@sougou
Copy link
Copy Markdown
Contributor Author

sougou commented Feb 11, 2018

@alainjobart this is ready for review. Feel free to add a bug number if applicable.
@acharis may also review. But I can't add you to the reviewers.

@acharis @rnavarro @demmer and others who currently rely on table ACLs: this is a breaking change because what was previously allowed may now fail.

@alainjobart
Copy link
Copy Markdown
Contributor

I love this solution, much more elegant, and correct! Thanks Sugu!

plan.Authorized is now an array built from plan.Permissions.
It's the authoritative list of table acl checks that need to
be performed. The previous code that used to chase down table
names in the plan is now simplified to only rely on Authorized.
MySQL does not support updatable subqueries. So, a construct like
update (select * from a) is invalid.
However, there are versions of SQL that support this and interpret
as something similar to an updatable view. So, in order to be
future-proof, I've made a corresponding modification to require
write permission for the table if such constructs are seen.
Copy link
Copy Markdown
Member

@demmer demmer left a comment

Choose a reason for hiding this comment

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

This looks really good to me.

@alainjobart
Copy link
Copy Markdown
Contributor

In #3651 a flag was used to enable the extra checks. Could we use a flag here to enable the extra checks on tables 1+ (leaving table 0 check always in), so that we can roll out the change slowly? And in a couple weeks, we can just remove the flag. It is unclear to us what impact this will have in production, so we'd like to have a quick way to disable the new behavior just in case...

@sougou
Copy link
Copy Markdown
Contributor Author

sougou commented Feb 12, 2018

That won't take it back to old behavior, because no checks were performed for joins before.
I can have a flag that skips checks if Table is nil. That will be close enough to old behavior.

@alainjobart
Copy link
Copy Markdown
Contributor

That flag sounds great. I am not sure who else is using table ACLs, and if they care about their roll out. If nobody else is, we can take care of removing the flag when we are done with our roll out.

@alainjobart
Copy link
Copy Markdown
Contributor

Thanks @sougou the flag looks good. I'll merge after travis passes. Then in a couple weeks we'll remove the legacy flag.

)

// TODO(sougou): remove after affected parties have transitioned to new behavior.
var legacyTableACL = flag.Bool("legacy-table-acl", false, "deprecated: this flag can be used to revert to the older table ACL behavior, which checked access for at most one table")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Could you change the default to true?

If set to false and someone creates a rollout without setting the flat to false then they'd roll out the new behavior. And we can't set the flag in our builds until it's present in the code. We can change the default after we've done the rollout.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We can solve that with undefok, right?
Whichever way we go, we'll see what's more convenient for us and we can fix it in the tree...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I agree with Alain; We should keep the default as false and use undefok to control the rollout of the new behavior.

@alainjobart alainjobart merged commit a0eae48 into vitessio:master Feb 14, 2018
@sougou sougou deleted the acl branch March 16, 2018 22:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants