Open tomasliumparas opened 2 years ago
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.
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.
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.
Okay, that makes sense
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?
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.
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
}
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.
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.
You have different TunnelBindingSubjects configured under it:
What could be the Domain then? *.somedomain.com? You might want to set the domain to:
dev.domain.tld
domain.tld
Lets say TunnelBindingSubject is app.dev.domain.com
You might want to configure:
app.sub.domain.tld/restricted
*.sub.domain.tld
domain.tld
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.
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
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.
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 :)
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 :)
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.
The below operator seems to implement this feature.
https://github.com/BojanZelic/cloudflare-zero-trust-operator
If we want some tunnels to leverage zero trust features and others to not do is it best to use both operators?
@adyanth Hey, thanks for update, will check it out!
out of interest any traction on that ?
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!
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.
Hey I was thinking what would be you thoughts about managing Zero Trust Applications too?
Creating/Assigning access policies?
Would you consider a PR?