> I am not sure what you mean by this would be used alongside internode and
> client TLS? The mutual TLS authentication allows the server to authenticate
> the client's identity using a client TLS certificate. The authenticators
> we're adding enable this functionality. There isn't an expectation that the
> same certificates be used. In fact, clients should not use the same
> certificates as the internode.


My apologies if questions (1 and 2) were a bit convoluted. I'm going to
walk through both client and internode below as I perceive the PR.

Client TLS connections have the client certificate checked against the
trust store (if client_encryption_options.require_client_auth is set to
true). It looks like the authenticator in the PR checks the identity in the
subject alternative name part of the certificate against identity / roles
relationships specified via CQL. This all makes sense to me, but to be
clear my question was whether the certificate used by the client is the
same as the certificate used to secure the connection. My initial reading
here is that *yes* the certificates are the same, there's only ever one
certificate, we're just looking in two locations for trust. We would first
be checking the certificate's trust before the request is ever processed
(is the CA or this certificate in the trust store). Then the SAN of the
certificate is utilized to determine *who* the request is being performed
by which is then matched up with a role and request processing continues as
usual.

Internode communication is where I started to get confused. It wasn't clear
where we were authorizing identities as trusted. We still have the
server_encryption_options.require_client_auth (similar to
client_encryption_options.require_client_auth) boolean to force checking
the trust of the provided certificate against our trust store. I was
looking for a way to specify either an allowed list of identities or a
pattern to match on. Rereading the PR showed me that we are extracting the
valid identities from the *outbound key*store (reference link
<https://github.com/apache/cassandra/pull/2372/files#diff-735a80fa49063fd54dfb776e8bacd825f90e74afdddd8cec72e87f8802d77a3aR77>).
This doesn't seem correct as the associated documentation
<https://github.com/apache/cassandra/blob/trunk/conf/cassandra.yaml#L1389-L1394>
in cassandra.yaml indicates this is where the public and private key
information is stored for a node's outbound (client) connections to other
nodes. Should this instead be the server_encryption_options.truststore
alongside trusted CA certificates? In either case it seems as though we
would need to load the public certificate for all servers in the cluster
(including the specified SPIFFE SAN). Is that correct? This means there's
no way (yet) to match against a specific pattern of identities, instead
they must all be explicitly allowed.

Back to my original question, it appears as though we are using a single
certificate for internode where we first check the trust chain of the
certificate then check the subject against a valid list in *some store*.
This is the same behavior for client certificates. The genesis of my
question was whether there would be *separate* certificates for the SPIFFE
work on top of the certificates used for the base TLS communication. *There
are not (which is good IMO) instead a SAN is expected to be included in the
certificate which is then used for checking identity.* (Note internode and
client certificates may still be separate and in most cases should be).
Given I've sorted out questions 1 and 2 in my mental model, question 3 is a
little different. I think the question is more *how do I manage
certificates and trust given these changes?* I think this can be answered
with:

For clients we provide a CA certificate in the client trust store and
identities via the new CQL syntax for mapping roles to SPIFFE identities.
Easy.

Internode communication is handled by adding a CA certificate to the server
trust store and outbound node client certificates to a store (which is not
clear at the moment per above) which include a SPIFFE identity as part of
their SAN.

Please let me know if this is accurate.

To recap open questions from above:

   1. Should we be using server_encryption_options.outbound_keystore or
   server_encryption_options.truststore for maintaining the list of trusted
   identities? The current PR uses the former, I propose the latter is more
   appropriate.
   2. Does each trusted certificate (containing an SPIFFE identity SAN)
   need to be loaded into the location specified in question 1 above?
   3. Is there any way to match on a pattern of an identity?

   For example my SPIFFE identity may be
*spiffe://example.com/payments/cassandra/1
   <http://example.com/payments/cassandra/1>*, in this example *cassandra/1*
   is the identifier for the node and I want to trust anything that
matches *spiffe://example.com/payments/cassandra/*
   <http://example.com/payments/cassandra/*>.* My initial reading here is
   that it is not possible at this time. We could use a common workload
   identifier across all nodes in the cluster (ie
*spiffe://example.com/payments/cassandra
   <http://example.com/payments/cassandra>*) then we would only need a
   single certificate in the trust store with the associated identity. This
   leads to my next question...
   4. From a documentation perspective, how would you describe a reference
   implementation? I think the project could benefit from a reference
   configuration including mTLS for clients and nodes with separate
   certificates for all components / nodes alongside a sample SPIFFE identity.
   (This question may be a bit outside of scope for the particular ticket /
   feature, but it's something to noodle on)

Again thank you for the contribution and patience as I work through the
code and mental model mapping this on top of my existing C* / TLS knowledge.

Cheers,
~Chris

Christopher Bradford



On Fri, Jun 2, 2023 at 2:57 PM Dinesh Joshi <djo...@apache.org> wrote:

>
>    1. Is there an expectation that this would be used alongside internode
>    and client TLS? Would the certificates be the same, different, or is that
>    an implementation detail for the specific deployment to determine?
>
>
> I am not sure what you mean by this would be used alongside internode and
> client TLS? The mutual TLS authentication allows the server to authenticate
> the client's identity using a client TLS certificate. The authenticators
> we're adding enable this functionality. There isn't an expectation that the
> same certificates be used. In fact, clients should not use the same
> certificates as the internode.
>
>
>    1. For some reason I'm having trouble understanding the internode
>    authentication portion of this ticket (authenticating a client with a
>    certificate makes sense vs just authenticating the connection). Why is this
>    needed on top of the connection-level TLS we have now?
>
>
> Current connection-level TLS only secures the TLS connection. It doesn't
> authenticate the peer. This adds the ability to authenticate the peer in
> addition to securing the TLS connection.
>
>
>    1. When an operator or DBA is looking to add a new identity is that
>    just handled as part of the new CQL statement or is there some certificate
>    management required on the nodes? I assume it's just the CA that needs to
>    be placed on the nodes to establish trust in the certificate itself then
>    authz happening within C* after determining the certificate can be trusted,
>    but want to be certain.
>
>
> Each deployment is different so certificate management isn't scope of the
> database itself. However, the operator can rotate the certificates using an
> external agent and Cassandra will pick them up through SSL hot reloading.
> We don't just rely on a CA trusting the client certificate, we extract the
> identity from the certificate (for example: SPIFFE) and ensure that it is
> allowed to access the cluster. This means someone can't just obtain a
> certificate signed by a CA that Cassandra cluster trusts and connect to it.
>
>
>    1. As a minor nit, should we include static certificates in the test
>    data? I see they expire in 2033 which is a fair way off, but I wonder if it
>    would make sense to generate the certificates as part of the test setup.
>
> Thanks for the feedback!
>

Reply via email to