Skip to main content

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 to X-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, the X-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.