authorize: add support for .pomerium and unauthenticated routes (#639)

* authorize: add support for .pomerium and unauthenticated routes
integration-tests: add test for forward auth dashboard urls

* proxy: fix ctx error test to return a 200 when authorize allows it
This commit is contained in:
Caleb Doxsey 2020-04-29 10:55:46 -06:00 committed by GitHub
parent e5c7c5b27e
commit b1d3bbaf56
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 158 additions and 69 deletions

View file

@ -5,10 +5,15 @@ import data.shared_key
default allow = false
# allow public
allow {
route := first_allowed_route(input.url)
route_policies[route].AllowPublicUnauthenticatedAccess == true
}
# allow by email
allow {
some route
allowed_route(input.url, route_policies[route])
route := first_allowed_route(input.url)
token.payload.email = route_policies[route].allowed_users[_]
token.valid
count(deny)==0
@ -16,8 +21,7 @@ allow {
# allow group
allow {
some route
allowed_route(input.url, route_policies[route])
route := first_allowed_route(input.url)
some group
token.payload.groups[group] == route_policies[route].allowed_groups[_]
token.valid
@ -26,8 +30,7 @@ allow {
# allow by impersonate email
allow {
some route
allowed_route(input.url, route_policies[route])
route := first_allowed_route(input.url)
token.payload.impersonate_email = route_policies[route].allowed_users[_]
token.valid
count(deny)==0
@ -35,8 +38,7 @@ allow {
# allow by impersonate group
allow {
some route
allowed_route(input.url, route_policies[route])
route := first_allowed_route(input.url)
some group
token.payload.impersonate_groups[group] == route_policies[route].allowed_groups[_]
token.valid
@ -45,8 +47,7 @@ allow {
# allow by domain
allow {
some route
allowed_route(input.url, route_policies[route])
route := first_allowed_route(input.url)
some domain
email_in_domain(token.payload.email, route_policies[route].allowed_domains[domain])
token.valid
@ -55,14 +56,24 @@ allow {
# allow by impersonate domain
allow {
some route
allowed_route(input.url, route_policies[route])
route := first_allowed_route(input.url)
some domain
email_in_domain(token.payload.impersonate_email, route_policies[route].allowed_domains[domain])
token.valid
count(deny)==0
}
# allow pomerium urls
allow {
contains(input.url, "/.pomerium/")
not contains(input.url,"/.pomerium/admin")
}
# returns the first matching route
first_allowed_route(input_url) = route {
route := [route | some route ; allowed_route(input.url, route_policies[route])][0]
}
allowed_route(input_url, policy){
input_url_obj := parse_url(input_url)
allowed_route_source(input_url_obj, policy)

View file

@ -65,6 +65,51 @@ test_email_denied {
}
}
test_public_allowed {
allow with data.route_policies as [{
"source": "example.com",
"AllowPublicUnauthenticatedAccess": true
}] with input as {
"url": "http://example.com",
"host": "example.com"
}
}
test_public_denied {
not allow with data.route_policies as [
{
"source": "example.com",
"prefix": "/by-user",
"allowed_users": ["bob@example.com"]
},
{
"source": "example.com",
"AllowPublicUnauthenticatedAccess": true
}
] with input as {
"url": "http://example.com/by-user",
"host": "example.com"
}
}
test_pomerium_allowed {
allow with data.route_policies as [{
"source": "example.com",
"allowed_users": ["bob@example.com"]
}] with input as {
"url": "http://example.com/.pomerium/",
"host": "example.com"
}
}
test_pomerium_denied {
not allow with data.route_policies as [{
"source": "example.com",
"allowed_users": ["bob@example.com"]
}] with input as {
"url": "http://example.com/.pomerium/admin",
"host": "example.com"
}
}
test_parse_url {
url := parse_url("http://example.com/some/path?qs")
url.scheme == "http"

File diff suppressed because one or more lines are too long

View file

@ -8,6 +8,7 @@ import (
"github.com/pomerium/pomerium/authorize/evaluator"
"github.com/pomerium/pomerium/internal/grpc/authorize"
"github.com/pomerium/pomerium/internal/log"
"github.com/pomerium/pomerium/internal/telemetry/trace"
)
@ -25,7 +26,19 @@ func (a *Authorize) IsAuthorized(ctx context.Context, in *authorize.IsAuthorized
RemoteAddr: in.GetRequestRemoteAddr(),
URL: getFullURL(in.GetRequestUrl(), in.GetRequestHost()),
}
return a.pe.IsAuthorized(ctx, req)
reply, err := a.pe.IsAuthorized(ctx, req)
log.Info().
// request
Str("method", req.Method).
Str("url", req.URL).
// reply
Bool("allow", reply.Allow).
Strs("deny-reasons", reply.DenyReasons).
Str("user", reply.User).
Str("email", reply.Email).
Strs("groups", reply.Groups).
Msg("authorize.grpc.IsAuthorized")
return reply, err
}
type protoHeader map[string]*authorize.IsAuthorizedRequest_Headers