<@U04UQ68083H> Hey! I am using Oathkeeper with Kra...
# ory-copilot
a
@chilly-king-10285 Hey! I am using Oathkeeper with Kratos and Keto. I have an endpoint that might be accessed by a logged-in user or non-user. I want to extract metadata if there is a user. Is it possible to use just a mutator without Kratos to get this metadata?
c
A message from kapa.ai
Yes, it is possible to use a mutator without Kratos to get metadata. Ory Oathkeeper provides several mutators that you can use to transform the HTTP request before it is forwarded to the upstream API. For example, you can use the
header
mutator to add session data to the HTTP headers, or the
id_token
mutator to generate a JWT with session information. Here is an example of a
header
mutator in an access rule:
Copy code
json {    "id": "some-id",    "upstream": {    "url": "<http://my-backend-service>"    },    "match": {    "url": "<http://my-app/api/<.*>>",    "methods": ["GET"]    },    "authenticators": [    {    "handler": "anonymous"    }    ],    "authorizer": {    "handler": "allow"    },    "mutators": [    {    "handler": "header",    "config": {    "headers": {    "X-User": "{{ print .Subject }}",    "X-Some-Arbitrary-Data": "{{ print .Extra.some.arbitrary.data }}"    }    }    }    ]   }
In this example, the
header
mutator adds the
X-User
and
X-Some-Arbitrary-Data
headers to the HTTP request. The values of these headers are extracted from the session data. However, please note that the session data is usually provided by an authenticator. If there is no user, the session data might not contain any meaningful information. In this case, you might want to use the
anonymous
authenticator to handle requests from non-users. For more information, please refer to the [Ory Oathkeeper documentation](https://www.ory.sh/docs/oathkeeper/pipeline/mutator#header-access-rule-example).
a
@chilly-king-10285 I have cookie based authentication with this config: cookie_session: enabled: true config: check_session_url: http://kratos-public:80/sessions/whoami preserve_path: true extra_from: "@this" subject_from: "identity.id" forward_http_headers: - Connect - Authorization - Cookie - X-Forwarded-For - X-Session-Token - X-Kratos-Authenticated-Identity-Id. How will the mutator know what the subject is without this part in the authenticator?
c
A message from kapa.ai
The
cookie_session
authenticator in your configuration is responsible for forwarding the request method, path, and headers to a session store (in this case, the Kratos public endpoint
/sessions/whoami
). If the session store returns a
200 OK
response with a body containing a
subject
field, the authenticator will set the subject appropriately. In your configuration, the
subject_from
field is set to
identity.id
, which means the subject will be set to the value of
identity.id
from the session store's response. Here is the relevant part of your configuration:
Copy code
yaml cookie_session:   enabled: true   config:     check_session_url: <http://kratos-public:80/sessions/whoami>     preserve_path: true     extra_from: "@this"     subject_from: "identity.id"
So, even without a specific part in the authenticator, the
subject_from
field in the configuration of the
cookie_session
authenticator instructs it on how to extract the subject from the session data. For more information, please refer to the [Ory Oathkeeper documentation](https://www.ory.sh/docs/oathkeeper/pipeline/authn#cookie_session).
i
If I understand you correctly, you would like to have a fallback. Like, if there is a cookie, the used session_cookie authenticator should kick in, otherwise the anonymous one. If this is the case, just configure the two authenticators in your rule. You can then use an id_token mutator and add the contents of the .Extra object to it. If there was an authorised user, you'll have everything about in in the corresponding claim, otherwise it will be empty.
a
@icy-manchester-83109 thank you very much, this is exactly what I meant. However, I do get an error that Extra.identity.metadata_public.user_id doesn't exist when I call the endpoint as a non-logged in user. I am using the two authenticators as you suggested, but with header mutator to extract the user_id as above. Do you know if it is possible to specify different mutator behaviour for different authenticators?
i
I assume you're creating a header or a jwt and while trying to create it, you get that error. If yes, you can simply check for the existence of the property like shown below in your template
Copy code
{{ with .Extra.identity }}{{ .metadata_public.user_id }}{{ else }} whatever {{ end }}
That's basically the way how to specify "different behaviour". Dispatching to different mutators to have real different behaviour is not possible with oathkeeper.
a
thank you so much!