greenpau / caddy-security

🔐 Authentication, Authorization, and Accounting (AAA) App and Plugin for Caddy v2. 💎 Implements Form-Based, Basic, Local, LDAP, OpenID Connect, OAuth 2.0 (Github, Google, Facebook, Okta, etc.), SAML Authentication. MFA/2FA with App Authenticators and Yubico. 💎 Authorization with JWT/PASETO tokens. 🔐
https://authcrunch.com/
Apache License 2.0
1.48k stars 73 forks source link

Use case check: sharing files with custom authn/authz #167

Open sagikazarmark opened 2 years ago

sagikazarmark commented 2 years ago

Hello!

First of all: I apologize for the wall of text. I wanted to make sure to describe my use case in details, so that the questions at the end can be put in context.

I've written a file sharing service that shares files from various object stores (called "drives"). These object stores can be "mounted" to paths (and optionally domains) (for example: /assets would be served from my S3 bucket, but gcs.mydomain.com/assets could serve files from a GCS bucket).

The service is integrated into with an other application that generates these files. By integration I mean that issuing credentials (JWT tokens for users, opaque tokens for service-to-service auth) and authorization (who can access what) are done by this other system (identity and authorization providers are abstracted, so theoretically, I could implement different providers).

To simplify things a bit: I wrote a custom HTTP server that calls out to external services for verifying credentials and authorizing subjects to access files from object stores.

As you could imagine, a considerable amount of the configuration overlaps with what a Caddyfile would contain for a similar use case. Therefore, I'm trying to rewrite this service as a Caddy module (basically: serving files from object stores).

I came across your project and I was amazed by the volume of features. Unfortunately, for that same reason, I'm having a hard time deciding whether it could serve my purposes (I should probably add that I'm planning to open source this module, so maybe not just my purposes) or what the gaps are (if any).

I tried to form a few questions that could (hopefully) help me decide (and I really hope this could work):

Can I chain multiple authentication methods?

For example, can I have a portal supporting both basic auth (and maybe even checking multiple identity providers) and JWT based auth?

Or to rephrase: how would I configure caddy-security to allow both basic auth (potentially backed by multiple ID stores) and JWT auth?

Is there a way to completely disable the UI?

In the particular use case I'm working on uses a different system for identity store and authz, so I probably don't need the UI or any of the management functions it provides. Can I disable it completely?

(This is strictly for my use case, less important if I get to open source the project).

Can I implement my own authorization providers?

As mentioned above, authorization is based on object attributes stored in another system. I would have to implement my own authorization layer for that (based on the URL, or rather the object key). Is that possible with this library? Can you give a few pointers how to do that?

I saw the so-called user transformers, but I'm not sure that helps in this case.

Can I customize the response given for authn/authz failures?

As a security feature, authz failures (ie. no access to a file) is returned as 404 as well so users can't guess file existence. (Actually, 403 would be equally fine). Is this something easily customizable?


These are the questions I came up with so far. I really hope I can use this library, because it looks awesome and from the looks of it, it implements at least 90% of what I need, so I'd hate to waste time to duplicate some of it.

I'd be happy to contribute back if we identify gaps that you believe might be interesting for this library.

Thanks for this library and appreciate any help you could give me related to the above!

greenpau commented 2 years ago

First of all: I apologize for the wall of text. I wanted to make sure to describe my use case in details, so that the questions at the end can be put in context.

@sagikazarmark , that is totally OK! 👍

Can I chain multiple authentication methods? For example, can I have a portal supporting both basic auth (and maybe even checking multiple identity providers) and JWT based auth? Or to rephrase: how would I configure caddy-security to allow both basic auth (potentially backed by multiple ID stores) and JWT auth?

The answer is partially yes. It is done by adding with basic and with api directives. See https://authp.github.io/docs/authorize/basic_api_key_auth

Is there a way to completely disable the UI? In the particular use case I'm working on uses a different system for identity store and authz, so I probably don't need the UI or any of the management functions it provides. Can I disable it completely? (This is strictly for my use case, less important if I get to open source the project).

Yes. It can be done in two ways: (1) using caddy path matches, (2) using disable settings directive, see https://github.com/authp/authp.github.io/issues/35

Can I implement my own authorization providers? As mentioned above, authorization is based on object attributes stored in another system. I would have to implement my own authorization layer for that (based on the URL, or rather the object key). Is that possible with this library? Can you give a few pointers how to do that? I saw the so-called user transformers, but I'm not sure that helps in this case.

This is not available out of the box. I would need to add facilities to "enrich" user identity with additional info from that third-party system.

Can I customize the response given for authn/authz failures? As a security feature, authz failures (ie. no access to a file) is returned as 404 as well so users can't guess file existence. (Actually, 403 would be equally fine). Is this something easily customizable?

If you are not authenticated, you get 401. If you are authenticated, but not authorized, you get 403.

More on redirects and status codes are here:

https://authp.github.io/docs/authorize/auto-redirect-url

https://authp.github.io/docs/authorize/acl-rbac#forbidden-access

sagikazarmark commented 2 years ago

@greenpau Thank you very much for your answers, really appreciate it!

Can I implement my own authorization providers? As mentioned above, authorization is based on object attributes stored in another system. I would have to implement my own authorization layer for that (based on the URL, or rather the object key). Is that possible with this library? Can you give a few pointers how to do that? I saw the so-called user transformers, but I'm not sure that helps in this case.

This is not available out of the box. I would need to add facilities to "enrich" user identity with additional info from that third-party system.

What I had in mind here is a custom authorization logic that based on some identity (eg. a user ID) can reach out to the other system to authorize access for a certain path.

Access is often controlled by group/role memberships and I'm not sure fetching all that into Caddy and making the authorization decision locally is scalable.

I'll start poking around caddy-security and let you know what I came up with.

Thanks again for the pointers!