Access rule pipeline
Read more about the principal components and execution pipeline of access rules if you haven't already. This chapter explains the different pipeline handlers available to you:
- Authentication handlers inspect HTTP requests (for example the HTTP Authorization Header) and execute some business logic that return true (for authentication ok) or false (for authentication invalid) as well as a subject ("user"). The subject is typically the "user" that made the request, but it could also be a machine (if you have machine-2-machine interaction) or something different.
- Authorization handlers: ensure that a subject ("user") has the right permissions. For example, a specific endpoint might only be accessible to subjects ("users") from group "admin". The authorizer handles that logic.
- Mutation handlers: transforms the credentials from incoming requests to credentials that your backend
understands. For example, the
Authorization: basic
header might be transformed toX-User: <subject-id>
. This allows you to write backends that don't care if the original request was an anonymous one, an OAuth 2.0 Access Token, or some other credential type. All your backend has to do is understand, for example, theX-User:
. - Error handlers: are responsible for executing logic after, for example, authentication or authorization failed. Ory Oathkeeper supports different error handlers and we will add more as the project progresses.
Templating
Some handlers such as the ID Token Mutator support templating using Golang Text Templates (examples). The sprig is also supported, on top of these two functions:
var _ = template.FuncMap{
"print": func(i interface{}) string {
if i == nil {
return ""
}
return fmt.Sprintf("%v", i)
},
"printIndex": func(element interface{}, i int) string {
if element == nil {
return ""
}
list := reflect.ValueOf(element)
if list.Kind() == reflect.Slice && i < list.Len() {
return fmt.Sprintf("%v", list.Index(i))
}
return ""
},
}
Session
In all configurations supporting templating instructions, it's possible to use the
AuthenticationSession
struct content.
type AuthenticationSession struct {
Subject string
Extra map[string]interface{}
Header http.Header
MatchContext MatchContext
}
type MatchContext struct {
RegexpCaptureGroups []string
URL *url.URL
Method string
Header http.Header
}
RegexpCaptureGroups
Configuration Examples
To use the subject extract to the token
{ "config_field": "{{ print .Subject }}" }
To use any arbitrary header value from the request headers
{ "config_field": "{{ .MatchContext.Header.Get \"some_header\" }}" }
To use an embedded value in the Extra
map (most of the time, it's a JWT token claim)
{ "config_field": "{{ print .Extra.some.arbitrary.data }}" }
To use a Regex capture from the request URL Note the usage of printIndex
to print a value from the array
{
"claims": "{\"aud\": \"{{ print .Extra.aud }}\", \"resource\": \"{{ printIndex .MatchContext.RegexpCaptureGroups 0 }}\""
}
To display a string array to JSON format, we can use the fmt printf function
{
"claims": "{\"aud\": \"{{ print .Extra.aud }}\", \"scope\": {{ printf \"%+q\" .Extra.scp }}}"
}
Note that the AuthenticationSession
struct has a field named Extra
which is a map[string]interface{}
, which receives varying
introspection data from the authentication process. Because the contents of Extra
are so variable, nested and potentially
non-existent values need special handling by the text/template
parser, and a print
FuncMap function has been provided to
ensure that non-existent map values will simply return an empty string, rather than <no value>
.
If you find that your field contain the string <no value>
then you have most likely omitted the print
function, and it's
recommended you use it for all values out of an abundance of caution and for consistency.
In the same way, a printIndex
FuncMap function is provided to avoid out of range exception to access in a array. It can be
useful for the regexp captures which depend of the request.