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

Zero Trust Applications support #67

Open
tomasliumparas opened this issue Nov 20, 2022 · 23 comments
Open

Zero Trust Applications support #67

tomasliumparas opened this issue Nov 20, 2022 · 23 comments

Comments

@tomasliumparas
Copy link

Hey I was thinking what would be you thoughts about managing Zero Trust Applications too?

Creating/Assigning access policies?

Would you consider a PR?

@adyanth
Copy link
Owner

adyanth commented Nov 20, 2022

Yes, I was planning on doing that once I could get around to finishing #43, which would need to create/access ZT applications.

I was thinking another CRD for ZT, which can attach to a TunnelBinding (WIP in #51/#63), creating and managing apps for the services referred there. When #43 comes in, the same CRD could attach at the other end to access the apps exposed via ZT.

What are your thoughts and structure for the same? Would love to hear them. I would consider a PR too, but let us hash out the details before you can start working on it to not step on each other.

@tomasliumparas
Copy link
Author

Cool! So initially I was thinking as separate CRD called for Example AccessApplication.

As far as I understand AccessApplication does not need to be tied to tunnel in any way? At least from Cloudflare point in the UI there are no relations between application and tunnel?

I am thinking about a controller which would reconcile AccessApplication CRDs itself and annotation support on services but in a bit different way - another controller watches the services and creates the AccessApplication CR which then gets reconciled.

That way there is still some basic annotations support, whole logic is inside AccessApplication controller and if some more advanced functionality is needed it can be implemented via AccessApplication CR.

@adyanth
Copy link
Owner

adyanth commented Nov 21, 2022

I am planning to move away from service annotations in #63 which is why I wanted the "AccessApplication" resource to map to the TunnelBinding object to apply the access policies to all the services listed in the TunnelBinding. So, just one controller is enough to reconcile the new CR.

Or if separation was needed, we would need two, AccessApplication and AccessApplicationBinding to map it to services.

@tomasliumparas
Copy link
Author

Okay, that makes sense

@tomasliumparas
Copy link
Author

What about if we could extend TunnelBindingSubject to accompany fields needed for ZT Access App instead of TunnelBinding?
That way each service exposed would have an ability to have its own ZT Access App?

And maybe add an the same struct to TunnelBinding that way there would be a possibility either to create a single AccessApp for all services inside the tunnel or different for each of them?

@adyanth
Copy link
Owner

adyanth commented Nov 21, 2022

Yes, that is exactly what I was thinking. That would be good to have the option of same per tunnel binding or per subject to override.

If that is the case, we need to evaluate the need/entries in AccessApplication, since the TunnelBinding controller itself can perform the reconciliation for applications too.

@tomasliumparas
Copy link
Author

I came with this after looking into API docs:

type TunnelBinding struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Subjects  []TunnelBindingSubject `json:"subjects"`
	TunnelRef TunnelRef              `json:"tunnelRef"`
	AccessApp AccessApp
	Status    TunnelBindingStatus `json:"status"`
}

type AccessApp struct {
	Name   string
	Domain string
	// Application type self_hosted,saas
	Type string
	// List of access policies
	AccessPolicies []AccessPolicy
	// Application settings
	Settings AccessAppSettings
}

type AccessAppSettings struct {
	// Authentication settins
	Authentication AccessAppAuthentication
	// Appearance settins
	Appearance AccessAppAppearance
	// Cookie settings
	Cookies AccessAppCookies
	// Additional settings
	Additional AccessAppAdditional
}

type AccessAppAuthentication struct {
	// The list of identiy providers which application is allowed to use. If empty all idps are allowed
	AllowedIdps []string
	// Skip identity provider selection if only one is configured
	InstantAuth bool
	// The amount of time that tokens issued for this application will be valid. Must be in the format 300ms or 2h45m. Valid time units are: ns, us (or µs), ms, s, m, h.
	SessionDuration string
}

type AccessAppAppearance struct {
	// Wether to show app in the launcher. Defaults to true.
	AppLauncherVisibility bool
	// Custom logo url
	CustomLogo string
}

type AccessAppCookies struct {
	// Sets the SameSite cookie setting, which provides increased security against CSRF attacks. [none,strict,lax]
	SameSiteAttribute string
	// Enables the HttpOnly cookie attribute, which increases security against XSS attacks.
	EnableHttpOnly bool
	// Protects against stolen authorization tokens. Do not use for non-HTTP applications that rely on protocols like SSH and RDP.
	EnableBindingCookie bool
}

type AccessAppAdditional struct {
	// Cloudflare will render an SSH terminal or VNC session for this application in a web browser. [ssh,vnc]
	BrowserRendering string
}

type AccessPolicy struct {
	Name    string
	Action  string
	Include []string
	Exclude []string
	Require []string
}

@adyanth
Copy link
Owner

adyanth commented Nov 21, 2022

The structure looks good, looks like it covers all the settings from ZT.

The TunnelBinding, if it contains the AccessApp, will not have a domain, since it changes for each app underneath, right? I would assume that the domain will be the same as the domain served by the tunnel, so that should not even be an option for the user (that would add a case where the tunnel serves a.domain.com and ZT protects b.domain.com doing nothing).

And this would also be part of the TunnelBindingSubject. This will be reconciled once the DNS record is created pointing to the tunnel, and teared down before DNS. Should be straightforward.

Thinking out loud, the lifetime of the access application is indeed the TunnelBinding object, so we do not need another controller to implement this, do correct me if I am wrong in this.

If you are planning to implement this, do allow me a couple of weeks to finish up #63 with the existing changes, so that you can build on top of that.

@tomasliumparas
Copy link
Author

The reason I added it was cause CF API expects that to be in subdomain.domain.com/path /path being optional and subdomain being optional.
So I thought it would make more sense to make it optional and let the user override it if needed.

Some use cases

AccessApp is set on the TunnelBinding

You have different TunnelBindingSubjects configured under it:

  • app1.dev.domain.tld
  • app2.dev.domain.tld

What could be the Domain then? *.somedomain.com?
You might want to set the domain to:

  • dev.domain.tld
  • domain.tld

AccessApp is set on TunnelBindingSubject

Lets say TunnelBindingSubject is app.dev.domain.com
You might want to configure:

  • app.sub.domain.tld/restricted
  • *.sub.domain.tld
  • domain.tld

@adyanth
Copy link
Owner

adyanth commented Nov 21, 2022

In the first use case, domain will be the domain configured for the Tunnel/ClusterTunnel, so domain.tld. I do not think you can just register a subdomain on Cloudflare, can you?

In the second use case, yes, those seem valid, so we could split it and allow user to enter the path. I still do not see a reason for the user to enter the domain, if it is not being served by the tunnel.

What would the use case look like for the tunnel serving app.domain.com, but the ZT to point to something.domain.com? ZT needs the domain to already point to something for it to work right?

*.sub.domain.tld does not seem right to be configured from the controller. If another app also adds the same policy, there might be a conflict. Allowing each to only manage their own subdomain prevents conflicts, and path is a good use case to include for users to customize.

@tomasliumparas
Copy link
Author

In the first use case, domain will be the domain configured for the Tunnel/ClusterTunnel, so domain.tld. I do not think you can just register a subdomain on Cloudflare, can you?

This thought was about the cases when you have some different TunBindSubjs configured under the same TunBind.
Lets say you have two microservices app1.dev.domain.tld and app1.dev.domain.tld and you would like only single AccessApplication protecting them both dev.domain.tld

My idea was if you specify AccessApp at TunBind level, you should get one that is like an umbrella for all and if you specify it under TunBindSubj level, you are getting well a single one for that subject.

But that might be overthinking things :)

In the second use case, yes, those seem valid, so we could split it and allow user to enter the path. I still do not see a reason for the user to enter the domain, if it is not being served by the tunnel.

Yeah, so I thought initially either to add Path or let the user override if needed.

What would the use case look like for the tunnel serving app.domain.com, but the ZT to point to something.domain.com? ZT needs the domain to already point to something for it to work right?

Yep, I feel the same

@tomasliumparas
Copy link
Author

Regarding the separate controller/Extending TunnelBinding controller

I am thinking can there be cases where you would like to configure only access applications without tunnels?
For example maybe you have some other tunnels which are not managed by cloudflare-operator, like some tunnels on vm's, like bastion hosts or something like that?

But I also agree it makes sense to make it a part of TunnelBinding.

@adyanth
Copy link
Owner

adyanth commented Nov 21, 2022

A single ZT protecting both app1 and app2, is that needed to be combined? User can specify policies at the TunnelBinding level and we can create two applications. Doing a single one might case issues when the services are deleted/modified, no?

Managing ZT for tunnels not managed by this controller might cause the same issues like the tunnel being deleted but us trying to configure ZT causing failures.

Other than that, I think we are on the same page :)

@tomasliumparas
Copy link
Author

Doing a single one might case issues when the services are deleted/modified, no?

Yeah, that might be correct.

So TunnelBinding level AccessApp would act as some default settings for all the Subjects?

I think I am okay with that :)

@adyanth
Copy link
Owner

adyanth commented Dec 11, 2022

Hey @tomasliumparas I merged #63 yesterday. You should be good to base off of the tunnel binding to add these! Thanks again for your interest and contribution.

Edit: Please use AccessConfig instead of AccessApp since that makes more sense naming wise.

@adyanth
Copy link
Owner

adyanth commented Jan 2, 2023

The below operator seems to implement this feature.

https://github.com/BojanZelic/cloudflare-zero-trust-operator

@thedjpetersen
Copy link

If we want some tunnels to leverage zero trust features and others to not do is it best to use both operators?

@tomasliumparas
Copy link
Author

@adyanth Hey, thanks for update, will check it out!

johnallen3d added a commit to johnallen3d/argocd-demo that referenced this issue Aug 14, 2024
It would appear that the cloudflare-operator is a bit out of date and
does not support the current version of cloudflare tunnels (eg.
zero-trust).

adyanth/cloudflare-operator#67 (comment)
@stiliajohny
Copy link

out of interest any traction on that ?

@adyanth
Copy link
Owner

adyanth commented Oct 9, 2024

Nothing from me. I have let this coast along for now, since it perfectly meets my use case and currently do not have plans (or time) implementing it myself. Although I'll be more than happy to review ideas and PRs!

@tomasliumparas
Copy link
Author

Hey @adyanth,

The need for this appeared again for me. I am planning on making a PR based on the above in the upcoming 2-3weeks.
I reviewed the cloudflare-zero-trust-operator, but for me it makes more sense to have a single operator which handles both tunnels and apps.

@tomasliumparas
Copy link
Author

@adyanth I added the PR with initial works. Still have some things to complete

@tomasliumparas
Copy link
Author

@adyanth technical details are done.
What is remaining is documentation changes

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

No branches or pull requests

4 participants