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

CASSSIDECAR-161: Add RBAC Authorization support in Sidecar #165

Merged
merged 53 commits into from
Jan 20, 2025

Conversation

sarankk
Copy link
Contributor

@sarankk sarankk commented Dec 16, 2024

No description provided.

Copy link
Contributor

@nvharikrishna nvharikrishna left a comment

Choose a reason for hiding this comment

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

Reviewed it partially. Will continue to review.

@sarankk
Copy link
Contributor Author

sarankk commented Dec 20, 2024

Thanks for the review @nvharikrishna and @bbotella appreciate it, addressed your comments.

@sarankk sarankk force-pushed the authorization branch 2 times, most recently from bd34d9e to d88b2db Compare December 20, 2024 22:30
Copy link
Contributor

@nvharikrishna nvharikrishna left a comment

Choose a reason for hiding this comment

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

Few more comments.

Copy link

@bbotella bbotella left a comment

Choose a reason for hiding this comment

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

Thanks a lot for addressing so many comments! Just a couple of nits, but it's a +1 from my end (nb).

Copy link
Contributor

@yifan-c yifan-c left a comment

Choose a reason for hiding this comment

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

submit what I have so far.

// SSTable related permissions
public static final Permission UPLOAD_SSTABLE = new WildcardPermission("UPLOAD:SSTABLE");
public static final Permission IMPORT_SSTABLE = new WildcardPermission("IMPORT:SSTABLE");
public static final Permission STREAM_SSTABLE = new WildcardPermission("STREAM:SSTABLE");
Copy link
Contributor

Choose a reason for hiding this comment

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

What about using READ to replace both VIEW and STREAM? Do we need to distinguish between those 2 read operations?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should we have READ and STREAM. We can use read for listing snapshots, reading topology, listing restore job in place of VIEW to align with http methods. STREAM feels like a separate action, hence distinction?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

One for use case for separating READ and STREAM . We have to allow permission for listing cdc segments and streaming them, currently we have READ:CDC and STREAM:CDC separately.

Copy link
Contributor

@yifan-c yifan-c left a comment

Choose a reason for hiding this comment

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

Good stuff.
Besides the inline comments, I do have one more question. How do operators configures the permissions in the sidecar table?

@sarankk
Copy link
Contributor Author

sarankk commented Jan 7, 2025

Good stuff.
Besides the inline comments, I do have one more question. How do operators configures the permissions in the sidecar table?

Currently operators will have to directly insert into sidecar role_permissions_v1 table for granting sidecar related permissions and use GRANT cql grammer for granting Cassandra related permissions

Copy link
Contributor

@nvharikrishna nvharikrishna left a comment

Choose a reason for hiding this comment

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

Few minor comments, otherwise, I'm good from my side.


/**
* sidecar_internal.role_permissions_v1 table holds custom sidecar permissions that are not stored in Cassandra.
* Permissions are stored against resource.
Copy link
Contributor

Choose a reason for hiding this comment

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

Permissions are stored against both role and resource right (both role and resource are part of primary key)?

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, I ported over the same schema we have in Cassandra

return getAllRolesAndPermissions;
}

private static class CqlLiterals
Copy link
Contributor

Choose a reason for hiding this comment

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

This private static class is holding only one static method. Any reason to have this class? Can the static method of this class can be part of its parent?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We have followed this approach in other TableSchema classes, I followed pattern for consistency

public Set<Authorization> requiredAuthorizations()
{
List<String> eligibleResources = VariableAwareResource.DATA_WITH_KEYSPACE.expandedResources();
return Collections.singleton(SidecarPermissions.READ_RING.toAuthorization(eligibleResources));
Copy link
Contributor

Choose a reason for hiding this comment

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

Doesn't it need authorization/permission for keyspace?

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 it does, in Cassandra if user has permission for data resource then they get access to all keyspaces under data. Hence we are expanding resources to allow access when user has access to a wider resource.

/**
* Test for {@link AccessProtectedRouteBuilder}
*/
public class AccessProtectedRouteBuilderTest
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add 1) a positive test and 2) build AcessProtectedRouteBuilder without any AccessProtected handler?

Copy link
Contributor

@frankgh frankgh left a comment

Choose a reason for hiding this comment

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

Added a couple more comments that we need to address.

@@ -16,21 +16,21 @@
* limitations under the License.
*/

package org.apache.cassandra.sidecar.exceptions;
package org.apache.cassandra.sidecar.common.server.exceptions;
Copy link
Contributor

Choose a reason for hiding this comment

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

let's avoid moving classes to another package.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't see the exception there I see it under org.apache.cassandra.sidecar.exceptions

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oh looks like this is a old comment

@@ -1,101 +1,38 @@
/*
Copy link
Contributor

Choose a reason for hiding this comment

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

we should preserve the license header.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not understanding

Copy link
Contributor Author

Choose a reason for hiding this comment

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

again looks like an old comment.

Comment on lines 136 to 146
Preconditions.checkArgument(router != null, "Router must be set");
Preconditions.checkArgument(method != null, "Http method must be set");
Preconditions.checkArgument(endpoint != null && !endpoint.isEmpty(), "Endpoint must be set");
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT, use Objects.requireNonNull 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.

I check for empty string too endpoint != null && !endpoint.isEmpty()

CassandraInputValidationConfiguration inputValidationConfiguration
= new CassandraInputValidationConfigurationImpl(DEFAULT_FORBIDDEN_KEYSPACES,
// some tests generate table folders with -
"[a-zA-Z][a-zA-Z0-9_-]{0,47}",
Copy link
Contributor

Choose a reason for hiding this comment

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

this is not correct. For the stream sstable from snapshot endpoint we will get a table from the path that has the tableId. We should remove tableId from the path to be able to correctly validate. Otherwise my suspicion is that you will always get unauthorized for the table, because it won't match the table name

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, will update this

Copy link
Contributor

@frankgh frankgh left a comment

Choose a reason for hiding this comment

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

+1 thanks for this work!

@frankgh frankgh merged commit 5a19e34 into apache:trunk Jan 20, 2025
@frankgh frankgh deleted the authorization branch January 20, 2025 00:09
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.

5 participants