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

[Feature Request] Multi-Tenant Authentication #179

Open
dipack95 opened this issue Nov 13, 2024 · 15 comments · May be fixed by #208
Open

[Feature Request] Multi-Tenant Authentication #179

dipack95 opened this issue Nov 13, 2024 · 15 comments · May be fixed by #208
Assignees

Comments

@dipack95
Copy link
Contributor

Hi! We're considering using piko to host a reverse proxy for our services that will be deployed in customer clouds. As we were taking a look at how authentication would work for the piko agents that would run alongside those services in customer clouds, we noticed that piko requires the same token to be used by all the agents.

Background -- we allow some of our customers to host some of our services in their own clouds/data centers. We recommend they host these services in a fault-tolerant manner, i.e. using k8s, or a load-balancer with multiple instances of the service behind it. The plan would be instantiate a piko agent on each instance of the service, using the same endpoint name for each cluster, allowing the piko proxy service (hosted by us) to appropriately load balance between upstream clients using the same endpoint name.

This renders piko a non-starter for us at this point, since the compromise of a single agent would mean we'd need to rotate the secret across all the service deployments in customer clouds, which as you can imagine is a difficult thing to coordinate at the best of times.

Is there a plan to introduce per-service authentication tokens? Would be happy to contribute towards making such a thing possible too.

@andydunstall
Copy link
Owner

andydunstall commented Nov 14, 2024

Hi @dipack95

we noticed that piko requires the same token to be used by all the agents

Just to clarify, Piko supports JWT tokens, using either a HMAC secret key, RSA public key, or ECDSA public key to authenticate requests. Therefore each agent can have a separate JWT token (with different claims), as long as they can all be verified by the Piko server

we'd need to rotate the secret across all the service deployments in customer clouds

Ok, so your issue is you want different secret/public keys to verify different agents?

It isn't something I've thought about much before, though adding a kind of multi-tenant system could be a good option? Such as if you can configure authentication (and maybe other configuration options in the future) per-tenant, then each tenant identifies itself with an x-piko-tenant header (plus auth header)?

Such as:

tenants:
- id: d8b9cd0b
  auth:
    hmac_secret_key: ce6e56f8-b62d-49d7-8ac9-4e44d9db7e49
- id: 968f7321
  auth:
    hmac_secret_key: a0cf0b93-0799-47a5-a5b1-2587f18474b2

Then an agent (or Go client) can be configured with both --connect.token and --connect.tenant?

@dipack95
Copy link
Contributor Author

Therefore each agent can have a separate JWT token (with different claims), as long as they can all be verified by the Piko server

Just so I understand this correctly, in case we use the asymmetric key path, each of the agents would still need to use the public key (RSA or ECDSA) to sign their JWT, with the only possible difference in the claim being what endpoints they are meant for, right? Based on this example.

Ok, so your issue is you want different secret/public keys to verify different agents?

Yeah, a multi-tenant model would make sense. We could define the keys to use for each tenant in the server config file somehow (your example makes sense to me), where the id parameter would correspond to a tenant ID (or possibly endpoint name) that the agent would then send along with the token.

I would think we could keep the current --connect.token semantics for the key/token itself, and add a --connect.id parameter. (or rely on the endpoint name for the tenant ID)

@andydunstall

@andydunstall
Copy link
Owner

Just so I understand this correctly, in case we use the asymmetric key path, each of the agents would still need to use the public key (RSA or ECDSA) to sign their JWT, with the only possible difference in the claim being what endpoints they are meant for, right?

Yep thats right

Yeah, a multi-tenant model would make sense

Ok cool, I'll try to get to that soon

@skaravad
Copy link

skaravad commented Dec 1, 2024

Just a thought based on #195 , you can have a client cert per agent which can enable variety of options based on client cert Common Name, Serial Number etc (only for Layer 7) by having a Reverse Proxy terminating and authenticating TLS clients , you can then revoke certs , route clients to different piko server backends based on some additional client cert attributes.

On a side note, given the configuration is based on a static config YAML, how multi-tenanted configuration would scale ? as the config needs to be more dynamic (so some persistent store like RAFT might be needed along with some options to create dynamic tenant-Ids and config and dynamic-reload)

@andydunstall
Copy link
Owner

by having a Reverse Proxy terminating and authenticating TLS clients , you can then revoke certs , route clients to different piko server backends based on some additional client cert attributes

yeah i agree a similar thing can be achieved with a proxy in front of piko, though i still think multi tenant support within Piko is still useful

given the configuration is based on a static config YAML, how multi-tenanted configuration would scale ?

I agree if your adding and removing tenants often this will become a problem, though I'll avoid coupling the issues of multi tenant support and dynamic configuration support

@andydunstall
Copy link
Owner

@dipack95 sorry I've been quite busy so haven't had a chance to work on this yet (I'll have time off from work in December so should be able to work on it properly)

How urgent is this for you? Are you still planning to use Piko if this is added?

@dipack95
Copy link
Contributor Author

dipack95 commented Dec 2, 2024

@andydunstall This is important for us for sure, but we're still planning on deploying Piko in some capacity in the meantime!

@andydunstall
Copy link
Owner

@dipack95 ok great, I'll make sure to try and complete this by the end of the month (again sorry I haven't had much time over the past few weeks)

@dipack95
Copy link
Contributor Author

Hi @andydunstall

As an update here, we're planning on deploying Piko with its current feature set (would love a version bump that would include #183!) by using an authorisation server that can generate a signed JWT, in exchange for an API key, used by the Piko agents installed on client hardware. This method seems to work for us at the moment, in lieu of multi-tenant support, since rotating the singular key pair (controlled by our authorisation server) would be enough to invalidate any existing JWTs.

The problem here is that the Piko server seems to terminate the Piko agents' connection to the upstream servers once the JWT has expired (using the exp JWT claim), which as you can imagine is an issue in maintaining constant communication with whatever the Piko agent is proxying connections for.

Our thinking is that if there's a way for Piko agents to swap JWTs without killing the connection, we could have a workable solution here for our use case.

@andydunstall
Copy link
Owner

andydunstall commented Dec 10, 2024

would love a version bump that would include #183!

Sure will tag (Edit: https://github.com/andydunstall/piko/releases/tag/v0.6.4)

Our thinking is that if there's a way for Piko agents to swap JWTs without killing the connection, we could have a workable solution here for our use case.

Thats possible but it would be quite a big task (probably bigger than multi tenant support). Would a config option to avoid killing the connection when the JWT expires suit your use case as a quick workaround?

@dipack95
Copy link
Contributor Author

Would a config option to avoid killing the connection when the JWT expires suit your use case as a quick workaround?

@andydunstall Yeah I think that should tide us over for now! Thank you!

@andydunstall
Copy link
Owner

Ok cool - I'll add this weekend

@andydunstall
Copy link
Owner

andydunstall commented Dec 15, 2024

@dipack95 I've added #204, please let me know if this works for you before I merge (--upstream.auth.disable-disconnect-on-expiry)

@dipack95
Copy link
Contributor Author

Thank you @andydunstall! That works great for us.

@andydunstall andydunstall self-assigned this Dec 23, 2024
@andydunstall andydunstall changed the title [Feature Request] Per-endpoint authentication token [Feature Request] Multi-Tenant Authentication Dec 23, 2024
@andydunstall andydunstall linked a pull request Dec 23, 2024 that will close this issue
@andydunstall
Copy link
Owner

@dipack95 I've added basic upstream multi-tenant auth support in #208. Sorry it took so long :)

Please try it out and check everything works alright

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

Successfully merging a pull request may close this issue.

3 participants