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

Peer authentication beta API, aka mTLS beta #1241

Merged
merged 14 commits into from
Jan 31, 2020

Conversation

diemtvu
Copy link
Contributor

@diemtvu diemtvu commented Jan 22, 2020

No description provided.

@istio-testing istio-testing added the do-not-merge/work-in-progress Block merging of a PR because it isn't ready yet. label Jan 22, 2020
@googlebot googlebot added the cla: yes Set by the Google CLA bot to indicate the author of a PR has signed the Google CLA. label Jan 22, 2020
@istio-testing istio-testing added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Jan 22, 2020
@rshriram
Copy link
Member

@diemtvu take a look at my PR for sidecar TLS termination (one way tls) #1248 . I think this API can be nicely folded into the Sidecar api so that the entire TLS thing is coherent. We can relax certain semantics of the sidecars (like mandatory egress, etc.) to accommodate the tls policy

}

// Defines the mode of peer authentication.
Mode mode = 2;
Copy link
Member

Choose a reason for hiding this comment

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

you need to add per port override here as well. Currently we have a bug. if the authn policy is strict, it applies to all declared ingress ports on a sidecar even if the user wanted custom TLS on that ingress port, or no TLS for that matter.

Copy link
Member

Choose a reason for hiding this comment

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

You also need to surface the mechanism to identify the mesh mTLS using ALPNs or in case of @mdhume's use case, based on SNIs (wherein non sidecar clients are using istio mTLS certs to talk to servers with sidecar, but they cant send the ALPNs).

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'd like to postpone sni/alpn later, after we delivery the essential features. I've add MutualTls wrapper message, so that we can add configuration for them later.

For port override, I add a map from port (number) to MutualTls. I am a bit hesitant on this too, and would like to hide it first until we are sure it works well in all aspect. Wdyt?

@diemtvu diemtvu changed the title [WIP] Peer authentication beta API, aka mTLS beta Peer authentication beta API, aka mTLS beta Jan 29, 2020
@istio-testing istio-testing removed the do-not-merge/work-in-progress Block merging of a PR because it isn't ready yet. label Jan 29, 2020
security/v1beta1/peer_authentication.proto Outdated Show resolved Hide resolved
PERMISSIVE = 0;

// Connection is an mTLS tunnel (TLS with client cert must be presented).
STRICT = 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

Strict - and all access checks that are required on a connection - should be in the authorization API.

I think we have consensus that this is the place to have it - and we have time to implement it there (it should be the same effort as implementing this new API ).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The consensus actually is this API. Please check with @smawson and @louiscryan

message MutualTLS {
enum Mode {
// Connection can be either plaintext or mTLS tunnel.
PERMISSIVE = 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we want to continue to expose permissive as a user preference. AutoMTLS removes the need for permissive to be exposed and managed by user.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

autoMtls solves different problem. We need this API to do what the existing alpha API doing today.

Copy link
Member

Choose a reason for hiding this comment

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

Lets call it as UNSET. We can then fallback to permissive internally if needed. But if we are going ot have permissive as a dedicated option, I certainly do not want this to be the default enum. The default enum in that case should be unset=0, as it allows for proper inheritance.

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 can add UNSET, but want to use it for validation to make sure the mode must be set explicitly instead. We still need permissive, otherwise, overwrite policy for namespace/workload to permissive seems odd.

Inheritance can base on whether the message (MutualTLS) is set or not.

Wdyt?

STRICT = 1;

// Connection is not tunneled.
DISABLE = 2;
Copy link
Contributor

Choose a reason for hiding this comment

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

What does it mean ? We already have a mechanism to opt out a port from injection.

You mean we don't do auto-detection and other filters ? Plain text ? This is quite confusing for user, and should be part of Sidecar or networking APIs, since it doesn't apply to authentication ( there is no authentication on the plain text port).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It means mTLS is disable. I'm not sure what do you mean by the mechanism to opt out a port from injection and what does it have any thing to do in here.

@costinm
Copy link
Contributor

costinm commented Jan 29, 2020 via email

message PeerAuthentication {
// The selector determines the workloads to apply the ChannelAuthentication on.
// If not set, the policy will be applied to all workloads in the same namespace as the policy.
istio.type.v1beta1.WorkloadSelector selector = 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry, just realized: this will have very 'dramatic' impact on behavior, meaning that will select ports that are currently not selected - and break most of the stateful set.

We can't have users of the old API just switch to this API - and it's not even clear how it can work in general for those cases.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you mean the problem related to the pass-through inbound listener? I think we will need to secure all ports on workload with this API, and user may need to use permissive mode in those cases. It's better than today behavior, when users might not realize that their workloads are not protected and traffic is actually in plain-text.

@rshriram
Copy link
Member

I am 80% okay with costin's proposal of moving the "enforce mesh security" mode to the authZ api (with the ability to add exceptions per port). We can define inheritance mechanisms for this setting alone in the authZ api. One less CRD to contend with. And paves the way for incremental upgrade to the new model.

How we do the mesh security is our internal implementation detail (mtls, proxy protocol plus some other wrapper, etc.). But from user point of view, it is a 3 way set: mesh-transport is UNSET, REQUIRED, DISABLED. Internally, we can assume unset == permissive at global level, and at individual namespace/workload level, it can inherit from the parent.

@diemtvu
Copy link
Contributor Author

diemtvu commented Jan 30, 2020

I also agree that authZ can address 80% of the need. But the remain 20% (e.g disable mTLS, the need for sni/alpn config) is the reason I think we still need this. No matter if they are edge cases or not, if we need to invent a new way to do so, the cost is the same, if not more.

It's true that when we have better security transport, more intuitive authZ or networking API, this one can be diminished. But it could easily be a few quarters from now, and I don't see why we have to stop this.

// Mutual TLS settings.
message MutualTLS {
enum Mode {
INVALID = 0;
Copy link
Member

Choose a reason for hiding this comment

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

can you change this to UNSET ? Because this is an inherited field. So invalid doesn't make sense

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 actually don't want inherit in enum, but inherit if the message type field mtls is not set. Using INVALID to require user to explicitly set it.

Copy link
Contributor

Choose a reason for hiding this comment

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

With proto3 we can't distinguish unset from set to 0, so the default would be INVALID, which doesn't make sense.

With port settings people can leave this unset just to change a port setting without changing the default.

So rename to UNSET seems fine.

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 mean, if users want to inherit, they should not define mtls at all, e.g

  selector:
    match:
      app: foo
  portLevelMtls:
    8080:
       mode: DISABLE

Instead of

  selector:
    match:
      app: foo
  mtls: {}
  portLevelMtls:
    8080:
       mode: DISABLE

The INVALID is not accepted value (i.e we will reject with validation), which force the yaml must explicitly set the mode, so mtls: {} is not legit.

Anyway, I'm ok to change to UNSET if you think it's better to treat this as inherit.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

FYI, I add above example to the API comment. Let me know if it make sense. I happy to change to UNSET otherwise.

Copy link
Contributor

Choose a reason for hiding this comment

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

Just change it to UNSET.

Also is there a reason other than distinguishing between UNSET and missing that we're nesting mode inside MutualTLS message? Could we just inline that and just have the enum?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.
The reason for MutualTLS message is for future extension. Not sure if we will need any, but I don't want to get into a dead end.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK in that case UNSET is definitely right, because if you extend it we wouldn't be able to distinguish if they leave that unset but set some other field in MutualTLS. So LGTM.

@nrjpoddar
Copy link
Member

It looks this PR and #1248 have overlapping concerns. Additionally, these are big API changes which are pretty close to release-1.5, can we ratify them after the release?

@smawson
Copy link
Contributor

smawson commented Jan 30, 2020

We'd like to get these changes into 1.5 and handle #1248 after, since this is really just moving authentication policy to Beta. This is all likely to change with the introduction of improved transport security, but in the meantime users need a beta-level way to control the behavior of the mTLS code.

@rshriram can you give this another look?

@@ -0,0 +1,151 @@
// Copyright 2019 Istio Authors
Copy link
Contributor

Choose a reason for hiding this comment

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

2019->2020

// Mutual TLS settings.
message MutualTLS {
enum Mode {
// Inherit from parent.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we document the default value if this is mesh level setting (no parent in this case)?


// PeerAuthentication defines how traffic will be tunneled (or not) to the sidecar.
//
// Examples:
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably worth to give a mesh level policy example (i.e., use root namespace).

Copy link
Contributor

@liminw liminw left a comment

Choose a reason for hiding this comment

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

/lgtm

@istio-testing istio-testing merged commit 659a010 into istio:master Jan 31, 2020
// namespace: foo
// spec:
// selector:
// matchLabels:
Copy link

Choose a reason for hiding this comment

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

doe this mean we need to do additional look up for auto mTLS? could that be done efficiently?

@rshriram
Copy link
Member

We'd like to get these changes into 1.5 and handle #1248 after, since this is really just moving authentication policy to Beta. This is all likely to change with the introduction of improved transport security, but in the meantime users need a beta-level way to control the behavior of the mTLS code.

I spoke with @diemtvu offline. To make progress, I am okay with this API. I will trim the sidecar API to simply specify TLS settings per port for ports that have mTLS disabled in this API - as that is useful in VM context.

@costinm
Copy link
Contributor

costinm commented Jan 31, 2020 via email

@costinm
Copy link
Contributor

costinm commented Jan 31, 2020 via email

diemtvu added a commit to diemtvu/api that referenced this pull request Feb 6, 2020
* Peer authentication beta API, aka mTLS beta

* Add missing gen file

* Update CRD cue and re-gen"

* Add port level mtls

* Udate proto.lock after rebase

* Remove port level settings for now. We might add it later

* Re-gen

* Apply comment suggestions

* Add port level mTLS settings

* Add example for inherit parent settings

* Rename invalid to unset

* Rename invalid to unset

* Address comments

* Address comments
istio-testing pushed a commit that referenced this pull request Feb 6, 2020
* Peer authentication beta API, aka mTLS beta

* Add missing gen file

* Update CRD cue and re-gen"

* Add port level mtls

* Udate proto.lock after rebase

* Remove port level settings for now. We might add it later

* Re-gen

* Apply comment suggestions

* Add port level mTLS settings

* Add example for inherit parent settings

* Rename invalid to unset

* Rename invalid to unset

* Address comments

* Address comments
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. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants