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

Add SPIFFE independent multiple trust domain API. #1923

Closed
wants to merge 9 commits into from
Closed

Add SPIFFE independent multiple trust domain API. #1923

wants to merge 9 commits into from

Conversation

mathetake
Copy link
Member

@mathetake mathetake commented Mar 23, 2021

Now that Envoy side implementations (envoyproxy/envoy#14884, envoyproxy/envoy#15509) have landed upstream, and "independent multiple trust domain authN/Z" can be achieved in Istio. So this PR adds API for that.

References:

Signed-off-by: Takeshi Yoneda takeshi@tetrate.io

@istio-testing istio-testing added the do-not-merge/work-in-progress Block merging of a PR because it isn't ready yet. label Mar 23, 2021
@istio-policy-bot
Copy link

😊 Welcome @mathetake! This is either your first contribution to the Istio api repo, or it's been
awhile since you've been here.

You can learn more about the Istio working groups, code of conduct, and contributing guidelines
by referring to Contributing to Istio.

Thanks for contributing!

Courtesy of your friendly welcome wagon.

@google-cla google-cla bot added the cla: yes Set by the Google CLA bot to indicate the author of a PR has signed the Google CLA. label Mar 23, 2021
@istio-testing istio-testing added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Mar 23, 2021
@istio-testing
Copy link
Collaborator

Hi @mathetake. Thanks for your PR.

I'm waiting for a istio member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
@mathetake mathetake marked this pull request as ready for review March 23, 2021 02:16
@istio-testing istio-testing removed the do-not-merge/work-in-progress Block merging of a PR because it isn't ready yet. label Mar 23, 2021
@mathetake
Copy link
Member Author

cc @lizan

@lizan
Copy link
Contributor

lizan commented Mar 23, 2021

@myidpt @howardjohn PTAL

mesh/v1alpha1/config.proto Outdated Show resolved Hide resolved
mesh/v1alpha1/config.proto Outdated Show resolved Hide resolved
@lizan
Copy link
Contributor

lizan commented Mar 24, 2021

/ok-to-test

@istio-testing istio-testing added ok-to-test Set this label allow normal testing to take place for a PR not submitted by an Istio org member. needs-rebase Indicates a PR needs to be rebased before being merged and removed needs-ok-to-test labels Mar 24, 2021
mesh/v1alpha1/config.proto Outdated Show resolved Hide resolved
@istio-testing istio-testing added size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. and removed needs-rebase Indicates a PR needs to be rebased before being merged size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Mar 30, 2021
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
@istio-testing istio-testing added size/S Denotes a PR that changes 10-29 lines, ignoring generated files. and removed size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. labels Mar 30, 2021
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
// and its aliases.
// Note that we can have multiple certificate data for a same trust_domain.
// In that case, certificates with a same trust domain will be merged and used together to verify peer certificates.
repeated string trust_domains = 3;
Copy link
Member

Choose a reason for hiding this comment

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

How does this relate to trust domain defined above?

Copy link
Member Author

Choose a reason for hiding this comment

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

this is associated with the "additional" root ca (CertificateData) to be used to validate incoming peer certs. In contrast, the trust domain above is used for singing certs with this cluster's root ca (e.g. istio-ca-secret).

Copy link
Member

Choose a reason for hiding this comment

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

I see. May be add a comment related to it? I found it confusing so asked.

Copy link
Member

@linsun linsun Apr 2, 2021

Choose a reason for hiding this comment

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

+1 very confusing. Can we clarify this? Even in the names, such as cluster_trust_domains or mesh_trust_domains?

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think this is that confusing since this is a field of CertificateData which is not in the top-level MeshConfig. But I agree that this is a bit confusing. @costinm @howardjohn thoughts?

Choose a reason for hiding this comment

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

Is there a corresponding PR in the Istio Repo yet to handle Certificates for multiple TrustDomains? As of now, it is assumed that all these trustAnchors are intended for the configured mesh TrustDomain

@istio-testing istio-testing added the needs-rebase Indicates a PR needs to be rebased before being merged label Apr 2, 2021
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
@istio-testing istio-testing removed the needs-rebase Indicates a PR needs to be rebased before being merged label Apr 5, 2021
@istio-testing istio-testing added the needs-rebase Indicates a PR needs to be rebased before being merged label Apr 18, 2021
@istio-testing istio-testing removed the needs-rebase Indicates a PR needs to be rebased before being merged label Apr 19, 2021
@istio-testing
Copy link
Collaborator

@mathetake: The following test failed, say /retest to rerun all failed tests:

Test name Commit Details Rerun command
release-notes_api dc4e8a2 link /test release-notes_api

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here.

// and its aliases.
// Note that we can have multiple certificate data for a same trust_domain.
// In that case, certificates with a same trust domain will be merged and used together to verify peer certificates.
repeated string trust_domains = 3;
Copy link
Member

Choose a reason for hiding this comment

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

why is the trust_domains plural, does that means the certificate_data can belong to multi trust domains?

Copy link
Member Author

@mathetake mathetake Apr 20, 2021

Choose a reason for hiding this comment

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

yes. See discussion here: #1923 (comment) for example, it can be used for aliasing trust domains.

@mathetake
Copy link
Member Author

@costinm @howardjohn could you take another look? Thanks!

@@ -410,6 +410,10 @@ message Source {

// Optional. A list of negative match of remote IP blocks.
repeated string not_remote_ip_blocks = 10;

// Optional. A list of trust domains of peer certificates.
Copy link
Member

Choose a reason for hiding this comment

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

If I have mesh config:

trustDomain: foo
trustDomainAliases: [bar, baz]

and I set trustDomains=foo, do bar and baz apply?
what if I set trustDomains=baz?

Basically are aliases applied here?

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for putting another insight. I think we should implicitly apply foo and bar as well when only setting trustDomains=baz in line with the doc of trustDomainAliases saying "aliases are treated as the same trust domain". And this is how we can treat foo, bar and baz as the same trust domain.

so maybe should i put the comment about this behavior here?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, please. In this case, we should always treat foo, bar, baz as identical.
Normally, users should not specify the trust_domains when they apply the authz policy to the local trust domain. But if they did, trust domain aliasing also applies here.

Copy link
Member

@howardjohn howardjohn left a comment

Choose a reason for hiding this comment

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

LGTM, one small clarification

Copy link
Contributor

@costinm costinm left a comment

Choose a reason for hiding this comment

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

I am a bit concerned with the 3 names - trust_domain, trust_domain_aliasses and trust_domains. Note that trust_domain is used to indicate what we'll put in the certs we generate, and the aliases was introduced mainly for migrations - and doesn't make sense once
we have the more explicit trust bundles.

From the Spiffee spec: "implementations MUST securely associate bundle endpoints with their respective trust domain, nominally through explicit configuration of a <trust_domain_name, endpoint> tuple" - no mention of aliases, which can be represented by having more tuples ( except that it is discouraged to have same keys associated with different names !)

https://tools.ietf.org/html/rfc5280#section-4.2.1.10 has the concept of 'name constraints' and
'permittedSubtrees' - which can apply to both Spiffee URL SANs but also domain SANs and even IP certs. However those are built into the cert PEM - so wouldn't need any configuration on our side.

Same for OIDC - the 'trust domain' is built into the discovery URL.

In other words: I'm worried we're again reinventing the wheel and confusing people, like we did with few other things in security.

I am also worried about the 'mesh wide' / mesh operator applicability of the config - instead of using ProxyConfig which allows more specific targeting. Since DestinationRule, Policy, etc are driven by the mesh user - I don't see why the trust endpoints would be mesh-wide and controlled by operator.

So my alternate proposals:

  • add this to ProxyConfig instead ( or maybe even DestinationRule - combined with the proposal we just heard in Env/networking for improving verification of SANs )
  • either use a 'trustDomain' ( without aliases - see spiffee spec/recommendation ), or use the RFC5280 naming, mentioning that the constraints can also be loaded from the cert itself. Since this kind of constraining of a root cert is in no way specific to spiffee URL SANs - I would very much prefer the 'constraints' approach.
  • If the URL form is specified I would just document that for Istio we recommend using the OIDC format for the URL, which includes the 'trust domain' in the URL in a well-known form, and validate that.

@costinm
Copy link
Contributor

costinm commented May 3, 2021

I would also request having this reviewed by Env WG ( MeshConfig vs ProxyConfig ) and Networking ( vs DestinationRule, and how it can fit/interact with the new proposal for validation in DR ). In particular we have a pretty big disconnect between networking - defining SAN validations in DR and client SAN validation in Gateway - and mesh config terms that are only used in Spiffee ( like the fact we validate ones by default and others not, ownership of configs, etc ).

I think this is a very important and useful PR - I would love to see this replace the 'trustDomainAliases' with a more standards-based and consistrent/integrated solution.

@@ -222,6 +222,13 @@ message MeshConfig {
// The certificate is retrieved from the endpoint.
string spiffe_bundle_url = 2;
}

// Optional. Specify the list of trust domains to which this certificate data belongs.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// Optional. Specify the list of trust domains to which this certificate data belongs.
// Optional. Specify the list of trust domains to which this root of trust belongs.


// Optional. Specify the list of trust domains to which this certificate data belongs.
// If set, they are used for this root CA. Otherwise, this root CA is used for default trust domain
// and its aliases.
Copy link
Contributor

Choose a reason for hiding this comment

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

This becomes error prone now. If the user forgets to specify trust_domains, the external CAs will be able to impersonate the local CA. I think in the long term, we should mandate this field to be non-empty (ie, if it's empty, the CertificateData is invalid). How about if users want to use this to configure extra roots for the local trust domains. they should set "LOCAL" as the trust domain? We need to think about the backward compatibility, though. Istiod can log warnings in 1.11 when trust_domains is unset, and we mandate it in 1.12.

// Optional. Specify the list of trust domains to which this certificate data belongs.
// If set, they are used for this root CA. Otherwise, this root CA is used for default trust domain
// and its aliases.
// Note that we can have multiple certificate data for a same trust_domain.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// Note that we can have multiple certificate data for a same trust_domain.
// Note that we can have multiple roots of trust for a same trust domain.

// If set, they are used for this root CA. Otherwise, this root CA is used for default trust domain
// and its aliases.
// Note that we can have multiple certificate data for a same trust_domain.
// In that case, certificates with a same trust domain will be merged and used together to verify peer certificates.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// In that case, certificates with a same trust domain will be merged and used together to verify peer certificates.
// In that case, root certificates associated with the same trust domain will be merged and used together to verify peer certificates from that trust domain.

@@ -410,6 +410,10 @@ message Source {

// Optional. A list of negative match of remote IP blocks.
repeated string not_remote_ip_blocks = 10;

// Optional. A list of trust domains of peer certificates.
Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, please. In this case, we should always treat foo, bar, baz as identical.
Normally, users should not specify the trust_domains when they apply the authz policy to the local trust domain. But if they did, trust domain aliasing also applies here.

@mathetake
Copy link
Member Author

mathetake commented May 10, 2021

@costinm Thank you very much for putting your thoughts in detail.

add this to ProxyConfig instead ( or maybe even DestinationRule - combined with the proposal we just heard in Env/networking for improving verification of SANs )

Could you add reviewers from these WG to this PR? And I would appreciate it if you could put the link to the proposal.

either use a 'trustDomain' ( without aliases - see spiffee spec/recommendation ), or use the RFC5280 naming, mentioning that the constraints can also be loaded from the cert itself. Since this kind of constraining of a root cert is in no way specific to spiffee URL SANs - I would very much prefer the 'constraints' approach.

Agreed and now I would love to go with 'naming constraints' and I'm even thinking of removing 'trust_domain(s)' field, which seems much clearer and standardized. Does it make sense to you to remove the field and only support loading domains from naming constrains?

If the URL form is specified I would just document that for Istio we recommend using the OIDC format for the URL, which includes the 'trust domain' in the URL in a well-known form, and validate that.

sg but if a user wants to load a "inline" cert (via "pem" field or equivalent in the future), then this cannot be available. So I guess this would introduce another confusion on users. I would prefer we stick to either "naming constrians" approach or "trust_domain" (without "s") approach as you proposed above. WDYT?

@istio-testing istio-testing added the needs-rebase Indicates a PR needs to be rebased before being merged label May 12, 2021
@istio-testing
Copy link
Collaborator

@mathetake: PR needs rebase.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@mathetake
Copy link
Member Author

superseded by #2090

@mathetake mathetake closed this Oct 19, 2021
@mathetake mathetake deleted the spiffe-multiple-trust-domain branch October 19, 2021 04:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes Set by the Google CLA bot to indicate the author of a PR has signed the Google CLA. needs-rebase Indicates a PR needs to be rebased before being merged ok-to-test Set this label allow normal testing to take place for a PR not submitted by an Istio org member. size/S Denotes a PR that changes 10-29 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.