[ 
https://issues.apache.org/jira/browse/CASSANDRA-21546?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18101835#comment-18101835
 ] 

Francisco Guerrero commented on CASSANDRA-21546:
------------------------------------------------

Thanks Aparna for the patch and Stefan for the suggestions. Regarding the 
nesting of the configuration I think the concern underneath your suggestion is 
a good one, but I'd like to push back on the specific mechanism (nesting under 
{{role_manager.parameters}}) and keep {{default_role_initializer}} as a 
top-level {{ParameterizedClass}}. Here's my take:

The concern is real, but it's an API problem, not a configuration placement 
one. You're right that {{IDefaultRoleInitializer}} shouldn't be invisibly glued 
into {{CassandraRoleManager}}, and that a custom {{IRoleManager}} should be 
aware of it rather than silently ignore the capability. But where the keys sit 
in {{cassandra.yaml}} has no relationship on that; a custom implementor 
discovers the feature by reading the {{IRoleManager}} interface, not the YAML. 

I've addressed awareness where it actually lives: 
{{IRoleManager.defaultRoleInitializer()}} is the integration point, 
{{AuthConfig.applyAuth()}} instantiates the initializer from the top-level 
config and wires it in (before the role manager, since the role manager depends 
on it), and a custom {{IRoleManager}} can override that method to integrate 
however it needs. Nesting the keys wouldn't move that needle.

Here are some of the drawbacks for the nesting approach:

-  {{ParameterizedClass.parameters}} is {{Map<String,String>}}, so you can't 
embed a {{ParameterizedClass}} inside it. Nesting forces flat, stringly-typed 
keys ({{default_role_initializer_class_name}}, 
{{default_role_initializer_role}}, …) plus hand-rolled prefix-stripping — 
exactly the shape {{ParameterizedClass}} exists to avoid.
-  It stays consistent with every sibling — {{authenticator}}, {{authorizer}}, 
{{role_manager}}, {{network_authorizer}}, {{cidr_authorizer}}, 
{{internode_authenticator}} are all top-level {{ParameterizedClass}} fields 
that cross-validate at startup, and the initializer validates the same way.
-  The initializer isn't purely a role-manager concern: 
{{MutualTlsDefaultRoleInitializer.validateConfiguration()}} reaches across to 
the authenticator (it rejects an authenticator that can't do MTLS). Nesting it 
under {{role_manager}} misrepresents that coupling.
-  The {{authenticator.parameters.validator_class_name}} analogy you argue for 
is a leaf. A bare class name with no params of its own. The initializer carries 
its own parameters ({{role}}, {{password}}/{{identity}}/{{hash}}) and its own 
validation, so it's a full {{ParameterizedClass}}, not a leaf string.
- Top-level also keeps it compatible with {{ParameterizedClass}} 
config-generation tooling, which understands the {{{class_name, parameters}}} 
shape; flat prefixed strings reuse none of it.

I think the concern about the shipped initializers is valid. The initializers 
do {{INSERT INTO system_auth.roles}}, so they're storage-coupled to 
{{CassandraRoleManager}} and a genuinely custom {{IRoleManager}} couldn't reuse 
them as-is. I think the right answer to that is the typed contract on 
{{IRoleManager}} plus startup cross-validation (same as the rest of the auth 
stack), not YAML nesting.

I have pushed a couple of commits on top of Aparna's original patch, and 
Stefan's suggestions: 
https://github.com/apache/cassandra/compare/trunk...frankgh:cassandra:CASSANDRA-21546?expand=1

In the first commit, I try to fix the tests that broke after the rewrite and 
cleanup some dead code. However, this is where I decide to go back to the top 
level configuration approach. That's what the second commit does. I also add 
tests backfilling the change in the {{ParameterizedClass.toString}} method, and 
update the {{MutualTlsCertificateValidityPeriodTest}} test to use this feature 
so avoid having to add the role and identity needed for the test.

Happy to keep discussing if you still feel the coupling warrants nesting — but 
I'd argue the interface contract carries that weight better than the config 
layout does.

> Support pluggable default role initialization (avoid hardcoded superuser 
> password)
> ----------------------------------------------------------------------------------
>
>                 Key: CASSANDRA-21546
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-21546
>             Project: Apache Cassandra
>          Issue Type: Bug
>            Reporter: Aparna Naik
>            Assignee: Aparna Naik
>            Priority: Normal
>
> Cassandra's first-boot bootstrap hardcodes the creation of a cassandra 
> superuser role with a default password (cassandra). Every new cluster starts 
> with this guessable credential exposed until an operator manually rotates or 
> drops it, and deployments that already use mutual TLS have no way to 
> bootstrap a superuser identity without also creating this password-based one. 
> This ticket will make the default role bootstrap pluggable via a new 
> IDefaultRoleInitializer interface and default_role_initializer config option. 
> The existing password-based behavior will be the default implementation for 
> backward compatibility, and it will add a MutualTlsDefaultRoleInitializer 
> that instead maps a client certificate identity to the superuser role, so no 
> password credential needs to exist at all.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to