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.44k stars 70 forks source link

question: Single Identity Store/Provider granting access to one or more Domains/sites #99

Open iamjrock opened 2 years ago

iamjrock commented 2 years ago

I have searched the docs and could not find an example of this. Apologies in advance if I have missed it.

Scenario: 1) A single caddy instance that hosts (say) 10 completely different sites/domains. So 10 site blocks in the Caddyfile. 2) A single identity store/provider (let's assume SAML or LDAP) that provides:

Questions

A) How can we get caddy-security to read that list of domains and only allow access to the domains listed for that user?

B) Can it be achieved without setting up multiple (per site/domain) authorization policies, authentication portals and/or identity stores/providers in the Caddyfile?

greenpau commented 2 years ago

B) Can it be achieved without setting up multiple (per site/domain) authorization policies, authentication portals and/or identity stores/providers in the Caddyfile?

@iamjrock , typically, the way you deal with it is by using snippets. https://github.com/greenpau/caddy-security/issues/69#issuecomment-1075722666

Will the snippets solve it for you?

A) How can we get caddy-security to read that list of domains and only allow access to the domains listed for that user?

Could you please explain this use case? Is this local, LDAP, OAuth, SAML user?

iamjrock commented 2 years ago

@iamjrock , typically, the way you deal with it is by using snippets. #69 (comment)

Will the snippets solve it for you?

Yes snippets & imports are the standard way to reuse configs in a Caddyfile. I did not explain it very well, but I'm hoping the solution would not require the use of snippets.

Could you please explain this use case? Is this local, LDAP, OAuth, SAML user?

Let's take LDAP as the example.

Can we do something like:

1) Simplified Caddy file looks like this and serves 1,000 domains with the same https:// site block:

{
  on_demand_tls {
        ask https://exampl.com/check
  }

  security {
    ldap identity store contoso.com {
      ....
    }
    authentication portal myportal {
      ....
    }
    authorization policy mypolicy {
      ....
    }
  }

  https:// {
    tls {
        on_demand
    }
    @is_auth_path {
      path /auth*
    }
    route @is_auth_path {
      authenticate with myportal
    }
    route {
       authorize with mypolicy
    }
    ......
  }
} 

2) Users are stored in the LDAP IdP and each user has the custom LDAP attribute "HostsAllowed" which is (say) a comma delimited list of domains that this user is allowed to access.

3) When caddy-security receives this data for the user, before continuing with the usual authentication workflow, it checks {host} against the "HostsAllowed" custom attribute and looks for a match.

If there is a match, continue with auth workflow.

If there is no match, return an HTTP error (probably 403 or 404?).

Does that explanation help?

greenpau commented 2 years ago

Let's take LDAP as the example.

@iamjrock , thank you for the walk-through! 👍

Simplified Caddy file looks like this and serves 1,000 domains with the same https:// site block:

Pretty cool snippet. I like the approach 😄 You are definitely ahead of me, at least when it comes to structuring config. 👍

Users are stored in the LDAP IdP and each user has the custom LDAP attribute "HostsAllowed" which is (say) a comma delimited list of domains that this user is allowed to access.

When caddy-security receives this data for the user, before continuing with the usual authentication workflow, it checks {host} against the "HostsAllowed" custom attribute and looks for a match.

Let me replay your ask: You want to pull user attributes and then run rule analysis on the attributes and decide whether it is go/no-go?

(fyi, there is a similar concept with user transforms that allows to block a user on a certain field match)

iamjrock commented 2 years ago

Let me replay your ask: You want to pull user attributes and then run rule analysis on the attributes and decide whether it is go/no-go?

Yes that's about right. Except that I'm not looking for an extensive, generic rule engine. Rather, the only rule is something like (psuedo code):

if(!in_array({host}, {HostsAllowed})){
  error "Unauthorized" 401
}

Where HostsAllowed is an array of allowed domains, as received from the IdP in a user attribute.

That make sense?

greenpau commented 2 years ago

Will work on this next.

iamjrock commented 2 years ago

Will work on this next.

thank you!

iamjrock commented 2 years ago

Hi @greenpau , just wondering if you have had a chance to work on this one?

greenpau commented 2 years ago

@iamjrock , not yet. Vacation, family, health took precedence lately.

iamjrock commented 2 years ago

not yet. Vacation, family, health took precedence lately.

The right priorities! 👍