text: (window.webpackJsonp=window.webpackJsonp||[]).push([[24],{128:function(e,t,n){"use strict";n.d(t,"a",(function(){return b})),n.d(t,"b",(function(){return h}));var a=n(0),i=n.n(a);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?r(Object(n),!0).forEach((function(t){o(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):r(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function s(e,t){if(null==e)return{};var n,a,i=function(e,t){if(null==e)return{};var n,a,i={},o=Object.keys(e);for(a=0;a<o.length;a++)n=o[a],t.indexOf(n)>=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a<o.length;a++)n=o[a],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=i.a.createContext({}),u=function(e){var t=i.a.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},b=function(e){var t=u(e.components);return i.a.createElement(c.Provider,{value:t},e.children)},d={inlineCode:"code",wrapper:function(e){var t=e.children;return i.a.createElement(i.a.Fragment,{},t)}},p=i.a.forwardRef((function(e,t){var n=e.components,a=e.mdxType,o=e.originalType,r=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),b=u(n),p=a,h=b["".concat(r,".").concat(p)]||b[p]||d[p]||o;return n?i.a.createElement(h,l(l({ref:t},c),{},{components:n})):i.a.createElement(h,l({ref:t},c))}));function h(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=n.length,r=new Array(o);r[0]=p;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l.mdxType="string"==typeof e?e:a,r[1]=l;for(var c=2;c<o;c++)r[c]=n[c];return i.a.createElement.apply(null,r)}return i.a.createElement.apply(null,n)}p.displayName="MDXCreateElement"},96:function(e,t,n){"use strict";n.r(t),n.d(t,"frontMatter",(function(){return r})),n.d(t,"metadata",(function(){return l})),n.d(t,"toc",(function(){return s})),n.d(t,"default",(function(){return u}));var a=n(3),i=n(8),o=(n(0),n(128)),r={id:"authn",title:"Authenticators"},l={unversionedId:"pipeline/authn",id:"pipeline/authn",isDocsHomePage:!1,title:"Authenticators",description:"An authenticator is responsible for authenticating request credentials. ORY",source:"@site/docs/pipeline/authn.md",sourceDirName:"pipeline",slug:"/pipeline/authn",permalink:"/oathkeeper/docs/next/pipeline/authn",editUrl:"https://github.com/ory/oathkeeper/edit/master/docs/docs/pipeline/authn.md",version:"current",lastUpdatedBy:"Ricardo Iv\xe1n Vieitez Parra",lastUpdatedAt:1617528429,formattedLastUpdatedAt:"4/4/2021",frontMatter:{id:"authn",title:"Authenticators"},sidebar:"docs",previous:{title:"Access Rule Pipeline",permalink:"/oathkeeper/docs/next/pipeline"},next:{title:"Authorizers",permalink:"/oathkeeper/docs/next/pipeline/authz"}},s=[{value:"<code>noop</code>",id:"noop",children:[{value:"Configuration",id:"configuration",children:[]},{value:"Access Rule Example",id:"access-rule-example",children:[]}]},{value:"<code>unauthorized</code>",id:"unauthorized",children:[{value:"Configuration",id:"configuration-1",children:[]},{value:"Access Rule Example",id:"access-rule-example-1",children:[]}]},{value:"<code>anonymous</code>",id:"anonymous",children:[{value:"Configuration",id:"configuration-2",children:[]},{value:"Access Rule Example",id:"access-rule-example-2",children:[]}]},{value:"<code>cookie_session</code>",id:"cookie_session",children:[{value:"Configuration",id:"configuration-3",children:[]},{value:"Access Rule Example",id:"access-rule-example-3",children:[]}]},{value:"<code>bearer_token</code>",id:"bearer_token",children:[{value:"Configuration",id:"configuration-4",children:[]},{value:"Access Rule Example",id:"access-rule-example-4",children:[]}]},{value:"<code>oauth2_client_credentials</code>",id:"oauth2_client_credentials",children:[{value:"Configuration",id:"configuration-5",children:[]},{value:"Access Rule Example",id:"access-rule-example-5",children:[]}]},{value:"<code>oauth2_introspection</code>",id:"oauth2_introspection",children:[{value:"Configuration",id:"configuration-6",children:[]},{value:"Access Rule Example",id:"access-rule-example-6",children:[]}]},{value:"<code>jwt</code>",id:"jwt",children:[{value:"Configuration",id:"configuration-7",children:[]},{value:"Scope",id:"scope",children:[]},{value:"Access Rule Example",id:"access-rule-example-7",children:[]}]}],c={toc:s};function u(e){var t=e.components,n=Object(i.a)(e,["components"]);return Object(o.b)("wrapper",Object(a.a)({},c,n,{components:t,mdxType:"MDXLayout"}),Object(o.b)("p",null,"An authenticator is responsible for authenticating request credentials. ORY\nOathkeeper supports different authenticators and we will add more as the project\nprogresses."),Object(o.b)("p",null,'An authenticator inspects the HTTP request (e.g. the HTTP Authorization Header)\nand executes some business logic that returns true (for authentication ok) or\nfalse (for authentication invalid) as well as a subject ("user"). The subject is\ntypically the "user" that made the request, but it could also be a machine (if\nyou have machine-2-machine interaction) or something different.'),Object(o.b)("p",null,"Each authenticator has two keys:"),Object(o.b)("ul",null,Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"handler")," (string, required): Defines the handler (e.g. ",Object(o.b)("inlineCode",{parentName:"li"},"noop"),") to be used."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"config")," (object, optional): Configures the handler. Configuration keys vary\nper handler. The configuration can be defined in the global configuration\nfile, or per access rule.")),Object(o.b)("p",null,Object(o.b)("strong",{parentName:"p"},"Example")),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-json"},'{\n  "authenticators": [\n    {\n      "handler": "noop",\n      "config": {}\n    }\n  ]\n}\n')),Object(o.b)("p",null,"You can define more than one authenticator in the Access Rule. The first\nauthenticator that is able to handle the credentials will be consulted and other\nauthenticators will be ignored:"),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-json"},'{\n  "authenticators": [\n    {\n      "handler": "a"\n    },\n    {\n      "handler": "b"\n    },\n    {\n      "handler": "c"\n    }\n  ]\n}\n')),Object(o.b)("p",null,"If handler ",Object(o.b)("inlineCode",{parentName:"p"},"a")," is able to handle the provided credentials, then handler ",Object(o.b)("inlineCode",{parentName:"p"},"b")," and\n",Object(o.b)("inlineCode",{parentName:"p"},"c")," will be ignored. If handler ",Object(o.b)("inlineCode",{parentName:"p"},"a")," can not handle the provided credentials but\nhandler ",Object(o.b)("inlineCode",{parentName:"p"},"b")," can, then handler ",Object(o.b)("inlineCode",{parentName:"p"},"a")," and ",Object(o.b)("inlineCode",{parentName:"p"},"c")," will be ignored. Handling the provided\ncredentials means that the authenticator knows how to handle, for example, the\n",Object(o.b)("inlineCode",{parentName:"p"},"Authorization: basic")," header. It does not mean that the credentials are valid!\nIf a handler encounters invalid credentials, then other handlers will be ignored\ntoo."),Object(o.b)("h2",{id:"noop"},Object(o.b)("inlineCode",{parentName:"h2"},"noop")),Object(o.b)("p",null,"The ",Object(o.b)("inlineCode",{parentName:"p"},"noop")," handler tells ORY Oathkeeper to bypass authentication, authorization,\nand mutation. This implies that no authorization will be executed and no\ncredentials will be issued. It's basically a pass-all authenticator that allows\nany request to be forwarded to the upstream URL."),Object(o.b)("blockquote",null,Object(o.b)("p",{parentName:"blockquote"},"Using this handler is basically an allow-all configuration. It makes sense\nwhen the upstream handles access control itself or does not need any type of\naccess control.")),Object(o.b)("h3",{id:"configuration"},"Configuration"),Object(o.b)("p",null,"This handler is not configurable."),Object(o.b)("p",null,"To enable this handler, set:"),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-yaml"},"# Global configuration file oathkeeper.yml\nauthenticators:\n  noop:\n    # Set enabled to true if the authenticator should be enabled and false to disable the authenticator. Defaults to false.\n    enabled: true\n")),Object(o.b)("h3",{id:"access-rule-example"},"Access Rule Example"),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-sh"},'$ cat ./rules.json\n\n[{\n  "id": "some-id",\n  "upstream": {\n    "url": "http://my-backend-service"\n  },\n  "match": {\n    "url": "http://my-app/some-route",\n    "methods": [\n      "GET"\n    ]\n  },\n  "authenticators": [{\n    "handler": "noop"\n  }]\n}]\n\n$ curl -X GET http://my-app/some-route\n\nHTTP/1.0 200 Status OK\nThe request has been allowed!\n')),Object(o.b)("h2",{id:"unauthorized"},Object(o.b)("inlineCode",{parentName:"h2"},"unauthorized")),Object(o.b)("p",null,"The ",Object(o.b)("inlineCode",{parentName:"p"},"unauthorized")," handler tells ORY Oathkeeper to reject all requests as\nunauthorized."),Object(o.b)("h3",{id:"configuration-1"},"Configuration"),Object(o.b)("p",null,"This handler is not configurable."),Object(o.b)("p",null,"To enable this handler, set:"),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-yaml"},"# Global configuration file oathkeeper.yml\nunauthorized:\n  noop:\n    # Set enabled to true if the authenticator should be enabled and false to disable the authenticator. Defaults to false.\n    enabled: true\n")),Object(o.b)("h3",{id:"access-rule-example-1"},"Access Rule Example"),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-sh"},'$ cat ./rules.json\n\n[{\n  "id": "some-id",\n  "upstream": {\n    "url": "http://my-backend-service"\n  },\n  "match": {\n    "url": "http://my-app/some-route",\n    "methods": [\n      "GET"\n    ]\n  },\n  "authenticators": [{\n    "handler": "unauthorized"\n  }]\n}]\n\n$ curl -X GET http://my-app/some-route\n\nHTTP/1.0 401 Unauthorized\n')),Object(o.b)("h2",{id:"anonymous"},Object(o.b)("inlineCode",{parentName:"h2"},"anonymous")),Object(o.b)("p",null,"The ",Object(o.b)("inlineCode",{parentName:"p"},"anonymous")," authenticator checks whether or not an ",Object(o.b)("inlineCode",{parentName:"p"},"Authorization")," header is\nset. If not, it will set the subject to ",Object(o.b)("inlineCode",{parentName:"p"},"anonymous"),"."),Object(o.b)("h3",{id:"configuration-2"},"Configuration"),Object(o.b)("ul",null,Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"subject"),' (string, optional) - Sets the anonymous username. Defaults to\n"anonymous". Common names include "guest", "anon", "anonymous", "unknown".')),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-yaml"},"# Global configuration file oathkeeper.yml\nauthenticators:\n  anonymous:\n    # Set enabled to true if the authenticator should be enabled and false to disable the authenticator. Defaults to false.\n    enabled: true\n\n    config:\n      subject: guest\n")),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-yaml"},"# Some Access Rule: access-rule-1.yaml\nid: access-rule-1\n# match: ...\n# upstream: ...\nauthenticators:\n  - handler: anonymous\n    config:\n      subject: guest\n")),Object(o.b)("h3",{id:"access-rule-example-2"},"Access Rule Example"),Object(o.b)("p",null,"The following rule allows all requests to ",Object(o.b)("inlineCode",{parentName:"p"},"GET http://my-app/some-route")," and\nsets the subject name to the anonymous username, as long as no ",Object(o.b)("inlineCode",{parentName:"p"},"Authorization"),"\nheader is set in the HTTP request:"),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-shell"},'$ cat ./rules.json\n\n[{\n  "id": "some-id",\n  "upstream": {\n    "url": "http://my-backend-service"\n  },\n  "match": {\n    "url": "http://my-app/some-route",\n    "methods": [\n      "GET"\n    ]\n  },\n  "authenticators": [{\n    "handler": "anonymous"\n  }],\n  "authorizer": { "handler": "allow" },\n  "mutators": [{ "handler": "noop" }]\n}]\n\n$ curl -X GET http://my-app/some-route\n\nHTTP/1.0 200 Status OK\nThe request has been allowed! The subject is: "anonymous"\n\n$ curl -X GET -H "Authorization: Bearer foobar" http://my-app/some-route\n\nHTTP/1.0 401 Status Unauthorized\nThe request is not authorized because credentials have been provided but only the anonymous\nauthenticator is enabled for this URL.\n')),Object(o.b)("h2",{id:"cookie_session"},Object(o.b)("inlineCode",{parentName:"h2"},"cookie_session")),Object(o.b)("p",null,"The ",Object(o.b)("inlineCode",{parentName:"p"},"cookie_session")," authenticator will forward the request method, path and\nheaders to a session store. If the session store returns ",Object(o.b)("inlineCode",{parentName:"p"},"200 OK")," and body\n",Object(o.b)("inlineCode",{parentName:"p"},'{ "subject": "...", "extra": {} }')," then the authenticator will set the subject\nappropriately."),Object(o.b)("h3",{id:"configuration-3"},"Configuration"),Object(o.b)("ul",null,Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"check_session_url")," (string, required) - The session store to forward request\nmethod/path/headers to for validation."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"only")," ([]string, optional) - If set, only requests that have at least one of\nthe set cookies will be forwarded, others will be passed to the next\nauthenticator. If unset, all requests are forwarded."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"preserve_path")," (boolean, optional) - If set, any path in ",Object(o.b)("inlineCode",{parentName:"li"},"check_session_url"),"\nwill be preserved instead of replacing the path with the path of the request\nbeing checked."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"extra_from")," (string, optional - defaults to ",Object(o.b)("inlineCode",{parentName:"li"},"extra"),") - A\n",Object(o.b)("a",{parentName:"li",href:"https://github.com/tidwall/gjson/blob/master/SYNTAX.md"},"GJSON Path")," pointing\nto the ",Object(o.b)("inlineCode",{parentName:"li"},"extra")," field. This defaults to ",Object(o.b)("inlineCode",{parentName:"li"},"extra"),", but it could also be ",Object(o.b)("inlineCode",{parentName:"li"},"@this"),"\n(for the root element), ",Object(o.b)("inlineCode",{parentName:"li"},"session.foo.bar")," for\n",Object(o.b)("inlineCode",{parentName:"li"},'{ "subject": "...", "session": { "foo": {"bar": "whatever"} } }'),", and so on."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"subject_from")," (string, optional - defaults to ",Object(o.b)("inlineCode",{parentName:"li"},"subject"),") - A\n",Object(o.b)("a",{parentName:"li",href:"https://github.com/tidwall/gjson/blob/master/SYNTAX.md"},"GJSON Path")," pointing\nto the ",Object(o.b)("inlineCode",{parentName:"li"},"subject")," field. This defaults to ",Object(o.b)("inlineCode",{parentName:"li"},"subject"),". Example: ",Object(o.b)("inlineCode",{parentName:"li"},"identity.id")," for\n",Object(o.b)("inlineCode",{parentName:"li"},'{ "identity": { "id": "1234" } }'),".")),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-yaml"},"# Global configuration file oathkeeper.yml\nauthenticators:\n  cookie_session:\n    # Set enabled to true if the authenticator should be enabled and false to disable the authenticator. Defaults to false.\n    enabled: true\n\n    config:\n      check_session_url: https://session-store-host\n")),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-yaml"},"# Some Access Rule: access-rule-1.yaml\nid: access-rule-1\n# match: ...\n# upstream: ...\nauthenticators:\n  - handler: cookie_session\n    config:\n      check_session_url: https://session-store-host\n      only:\n        - sessionid\n")),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-yaml"},"# Some Access Rule Preserving Path: access-rule-2.yaml\nid: access-rule-2\n# match: ...\n# upstream: ...\nauthenticators:\n  - handler: cookie_session\n    config:\n      check_session_url: https://session-store-host/check-session\n      only:\n        - sessionid\n      preserve_path: true\n")),Object(o.b)("h3",{id:"access-rule-example-3"},"Access Rule Example"),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-shell"},'$ cat ./rules.json\n\n[{\n  "id": "some-id",\n  "upstream": {\n    "url": "http://my-backend-service"\n  },\n  "match": {\n    "url": "http://my-app/some-route",\n    "methods": [\n      "GET"\n    ]\n  },\n  "authenticators": [{\n    "handler": "cookie_session"\n  }],\n  "authorizer": { "handler": "allow" },\n  "mutators": [{ "handler": "noop" }]\n}]\n\n$ curl -X GET -b sessionid=abc http://my-app/some-route\n\nHTTP/1.0 200 OK\nThe request has been allowed! The subject is: "peter"\n\n$ curl -X GET -b sessionid=def http://my-app/some-route\n\nHTTP/1.0 401 Status Unauthorized\nThe request is not authorized because the provided credentials are invalid.\n')),Object(o.b)("h2",{id:"bearer_token"},Object(o.b)("inlineCode",{parentName:"h2"},"bearer_token")),Object(o.b)("p",null,"The ",Object(o.b)("inlineCode",{parentName:"p"},"bearer_token")," authenticator will forward the request method, path and\nheaders to a session store. If the session store returns ",Object(o.b)("inlineCode",{parentName:"p"},"200 OK")," and body\n",Object(o.b)("inlineCode",{parentName:"p"},'{ "subject": "...", "extra": {} }')," then the authenticator will set the subject\nappropriately."),Object(o.b)("h3",{id:"configuration-4"},"Configuration"),Object(o.b)("ul",null,Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"check_session_url")," (string, required) - The session store to forward request\nmethod/path/headers to for validation."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"preserve_path")," (boolean, optional) - If set, any path in ",Object(o.b)("inlineCode",{parentName:"li"},"check_session_url"),"\nwill be preserved instead of replacing the path with the path of the request\nbeing checked."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"extra_from")," (string, optional - defaults to ",Object(o.b)("inlineCode",{parentName:"li"},"extra"),") - A\n",Object(o.b)("a",{parentName:"li",href:"https://github.com/tidwall/gjson/blob/master/SYNTAX.md"},"GJSON Path")," pointing\nto the ",Object(o.b)("inlineCode",{parentName:"li"},"extra")," field. This defaults to ",Object(o.b)("inlineCode",{parentName:"li"},"extra"),", but it could also be ",Object(o.b)("inlineCode",{parentName:"li"},"@this"),"\n(for the root element), ",Object(o.b)("inlineCode",{parentName:"li"},"session.foo.bar")," for\n",Object(o.b)("inlineCode",{parentName:"li"},'{ "subject": "...", "session": { "foo": {"bar": "whatever"} } }'),", and so on."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"subject_from")," (string, optional - defaults to ",Object(o.b)("inlineCode",{parentName:"li"},"sub"),") - A\n",Object(o.b)("a",{parentName:"li",href:"https://github.com/tidwall/gjson/blob/master/SYNTAX.md"},"GJSON Path")," pointing\nto the ",Object(o.b)("inlineCode",{parentName:"li"},"sub")," field. This defaults to ",Object(o.b)("inlineCode",{parentName:"li"},"sub"),". Example: ",Object(o.b)("inlineCode",{parentName:"li"},"identity.id")," for\n",Object(o.b)("inlineCode",{parentName:"li"},'{ "identity": { "id": "1234" } }'),"."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"token_from")," (object, optional) - The location of the bearer token. If not\nconfigured, the token will be received from a default location -\n'Authorization' header. One and only one location (header, query, or cookie)\nmust be specified.",Object(o.b)("ul",{parentName:"li"},Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"header")," (string, required, one of) - The header (case insensitive) that\nmust contain a Bearer token for request authentication. It can't be set\nalong with ",Object(o.b)("inlineCode",{parentName:"li"},"query_parameter")," or ",Object(o.b)("inlineCode",{parentName:"li"},"cookie"),"."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"query_parameter")," (string, required, one of) - The query parameter (case\nsensitive) that must contain a Bearer token for request authentication. It\ncan't be set along with ",Object(o.b)("inlineCode",{parentName:"li"},"header")," or ",Object(o.b)("inlineCode",{parentName:"li"},"cookie"),"."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"cookie")," (string, required, one of) - The cookie (case sensitive) that must\ncontain a Bearer token for request authentication. It can't be set along\nwith ",Object(o.b)("inlineCode",{parentName:"li"},"header")," or ",Object(o.b)("inlineCode",{parentName:"li"},"query_parameter"))))),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-yaml"},"# Global configuration file oathkeeper.yml\nauthenticators:\n  bearer_token:\n    # Set enabled to true if the authenticator should be enabled and false to disable the authenticator. Defaults to false.\n    enabled: true\n\n    config:\n      check_session_url: https://session-store-host\n      token_from:\n        header: Custom-Authorization-Header\n        # or\n        # query_parameter: auth-token\n        # or\n        # cookie: auth-token\n")),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-yaml"},"# Some Access Rule: access-rule-1.yaml\nid: access-rule-1\n# match: ...\n# upstream: ...\nauthenticators:\n  - handler: bearer_token\n    config:\n      check_session_url: https://session-store-host\n      token_from:\n        query_parameter: auth-token\n        # or\n        # header: Custom-Authorization-Header\n        # or\n        # cookie: auth-token\n")),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-yaml"},"# Some Access Rule Preserving Path: access-rule-2.yaml\nid: access-rule-2\n# match: ...\n# upstream: ...\nauthenticators:\n  - handler: bearer_token\n    config:\n      check_session_url: https://session-store-host/check-session\n      token_from:\n        query_parameter: auth-token\n        # or\n        # header: Custom-Authorization-Header\n        # or\n        # cookie: auth-token\n      preserve_path: true\n")),Object(o.b)("h3",{id:"access-rule-example-4"},"Access Rule Example"),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-shell"},'$ cat ./rules.json\n\n[{\n  "id": "some-id",\n  "upstream": {\n    "url": "http://my-backend-service"\n  },\n  "match": {\n    "url": "http://my-app/some-route",\n    "methods": [\n      "GET"\n    ]\n  },\n  "authenticators": [{\n    "handler": "bearer_token"\n  }],\n  "authorizer": { "handler": "allow" },\n  "mutators": [{ "handler": "noop" }]\n}]\n\n$ curl -X GET -H \'Authorization: Bearer valid-token\' http://my-app/some-route\n\nHTTP/1.0 200 OK\nThe request has been allowed! The subject is: "peter"\n\n$ curl -X GET -H \'Authorization: Bearer invalid-token\' http://my-app/some-route\n\nHTTP/1.0 401 Status Unauthorized\nThe request is not authorized because the provided credentials are invalid.\n')),Object(o.b)("h2",{id:"oauth2_client_credentials"},Object(o.b)("inlineCode",{parentName:"h2"},"oauth2_client_credentials")),Object(o.b)("p",null,"This ",Object(o.b)("inlineCode",{parentName:"p"},"oauth2_client_credentials")," uses the username and password from HTTP Basic\nAuthorization (",Object(o.b)("inlineCode",{parentName:"p"},"Authorization: Basic base64(<username:password>)")," to perform the\nOAuth 2.0 Client Credentials grant in order to detect if the provided\ncredentials are valid."),Object(o.b)("p",null,"This authenticator will use the username from the HTTP Basic Authorization\nheader as the subject for this request."),Object(o.b)("blockquote",null,Object(o.b)("p",{parentName:"blockquote"},"If you are unfamiliar with OAuth 2.0 Client Credentials we recommend\n",Object(o.b)("a",{parentName:"p",href:"https://www.oauth.com/oauth2-servers/access-tokens/client-credentials/"},"reading this guide"),".")),Object(o.b)("h3",{id:"configuration-5"},"Configuration"),Object(o.b)("ul",null,Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"token_url")," (string, required) - The OAuth 2.0 Token Endpoint that will be\nused to validate the client credentials."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"retry")," (object, optional) - Configures timeout and delay settings for the\nrequest against the token endpoint",Object(o.b)("ul",{parentName:"li"},Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"give_up_after")," (string) timeout"),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"max_delay")," (string) time to wait between retries"))),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"required_scope")," ([]string, optional) - Sets what scope is required by the URL\nand when making performing OAuth 2.0 Client Credentials request, the scope\nwill be included in the request:")),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-yaml"},"# Global configuration file oathkeeper.yml\nauthenticators:\n  oauth2_client_credentials:\n    # Set enabled to true if the authenticator should be enabled and false to disable the authenticator. Defaults to false.\n    enabled: true\n\n    config:\n      token_url: https://my-website.com/oauth2/token\n")),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-yaml"},"# Some Access Rule: access-rule-1.yaml\nid: access-rule-1\n# match: ...\n# upstream: ...\nauthenticators:\n  - handler: oauth2_client_credentials\n    config:\n      token_url: https://my-website.com/oauth2/token\n")),Object(o.b)("h3",{id:"access-rule-example-5"},"Access Rule Example"),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-shell"},'$ cat ./rules.json\n\n[{\n  "id": "some-id",\n  "upstream": {\n    "url": "http://my-backend-service"\n  },\n  "match": {\n    "url": "http://my-app/some-route",\n    "methods": [\n      "GET"\n    ]\n  },\n  "authenticators": [{\n    "handler": "oauth2_client_credentials",\n    "config": {\n      "required_scope": ["scope-a", "scope-b"]\n    }\n  }],\n  "authorizer": { "handler": "allow" },\n  "mutators": [{ "handler": "noop" }]\n}]\n\n$ curl -X GET http://my-app/some-route\n\nHTTP/1.0 401 Status Unauthorized\nThe request is not authorized because no credentials have been provided.\n\n$ curl -X GET --user idonotexist:whatever http://my-app/some-route\n\nHTTP/1.0 401 Status Unauthorized\nThe request is not authorized because the provided credentials are invalid.\n\n$ curl -X GET --user peter:somesecret http://my-app/some-route\n\nHTTP/1.0 200 OK\nThe request has been allowed! The subject is: "peter"\n')),Object(o.b)("p",null,"In the background, a request to the OAuth 2.0 Token Endpoint (value of\n",Object(o.b)("inlineCode",{parentName:"p"},"authenticators.oauth2_client_credentials.token_url"),") will be made, using the\nOAuth 2.0 Client Credentials Grant:"),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre"},"POST /oauth2/token HTTP/1.1\nHost: authorization-server.com\n\ngrant_type=client_credentials\n&client_id=peter\n&client_secret=somesecret\n&scope=scope-a+scope-b\n")),Object(o.b)("p",null,"If the request succeeds, the credentials are considered valid and if the request\nfails, the credentials are considered invalid."),Object(o.b)("h2",{id:"oauth2_introspection"},Object(o.b)("inlineCode",{parentName:"h2"},"oauth2_introspection")),Object(o.b)("p",null,"The ",Object(o.b)("inlineCode",{parentName:"p"},"oauth2_introspection")," authenticator handles requests that have an Bearer\nToken in the Authorization Header (",Object(o.b)("inlineCode",{parentName:"p"},"Authorization: bearer <token>"),") or in a\ndifferent header or query parameter specified in configuration. It then uses\nOAuth 2.0 Token Introspection to check if the token is valid and if the token\nwas granted the requested scope."),Object(o.b)("blockquote",null,Object(o.b)("p",{parentName:"blockquote"},"If you are unfamiliar with OAuth 2.0 Introspection we recommend\n",Object(o.b)("a",{parentName:"p",href:"https://www.oauth.com/oauth2-servers/token-introspection-endpoint/"},"reading this guide"),".")),Object(o.b)("h3",{id:"configuration-6"},"Configuration"),Object(o.b)("ul",null,Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"introspection_url")," (string, required) - The OAuth 2.0 Token Introspection\nendpoint."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"scope_strategy"),' (string, optional) - Sets the strategy to be used to\nvalidate/match the token scope. Supports "hierarchic", "exact", "wildcard",\n"none". Defaults to "none".'),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"required_scope")," ([]string, optional) - Sets what scope is required by the URL\nand when performing OAuth 2.0 Client Credentials request, the scope will be\nincluded in the request."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"target_audience")," ([]string, optional) - Sets what audience is required by the\nURL."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"trusted_issuers")," ([]string, optional) - Sets a list of trusted token issuers."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"pre_authorization")," (object, optional) - Enable pre-authorization in cases\nwhere the OAuth 2.0 Token Introspection endpoint is protected by OAuth 2.0\nBearer Tokens that can be retrieved using the OAuth 2.0 Client Credentials\ngrant.",Object(o.b)("ul",{parentName:"li"},Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"enabled")," (bool, optional) - Enable pre-authorization. Defaults to false."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"client_id")," (string, required if enabled) - The OAuth 2.0 Client ID to be\nused for the OAuth 2.0 Client Credentials Grant."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"client_secret")," (string, required if enabled) - The OAuth 2.0 Client Secret\nto be used for the OAuth 2.0 Client Credentials Grant."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"token_url")," (string, required if enabled) - The OAuth 2.0 Token Endpoint\nwhere the OAuth 2.0 Client Credentials Grant will be performed."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"audience")," (string, optional) - The OAuth 2.0 Audience to be requested\nduring the OAuth 2.0 Client Credentials Grant."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"scope")," ([]string, optional) - The OAuth 2.0 Scope to be requested during\nthe OAuth 2.0 Client Credentials Grant."))),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"token_from")," (object, optional) - The location of the bearer token. If not\nconfigured, the token will be received from a default location -\n'Authorization' header. One and only one location (header, query, or cookie)\nmust be specified.",Object(o.b)("ul",{parentName:"li"},Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"header")," (string, required, one of) - The header (case insensitive) that\nmust contain a Bearer token for request authentication. It can't be set\nalong with ",Object(o.b)("inlineCode",{parentName:"li"},"query_parameter")," or ",Object(o.b)("inlineCode",{parentName:"li"},"cookie"),"."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"query_parameter")," (string, required, one of) - The query parameter (case\nsensitive) that must contain a Bearer token for request authentication. It\ncan't be set along with ",Object(o.b)("inlineCode",{parentName:"li"},"header")," or ",Object(o.b)("inlineCode",{parentName:"li"},"cookie"),"."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"cookie")," (string, required, one of) - The cookie (case sensitive) that must\ncontain a Bearer token for request authentication. It can't be set along\nwith ",Object(o.b)("inlineCode",{parentName:"li"},"header")," or ",Object(o.b)("inlineCode",{parentName:"li"},"query_parameter")))),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"introspection_request_headers")," (object, optional) - Additional headers to add\nto the introspection request."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"retry")," (object, optional) - Configure the retry policy",Object(o.b)("ul",{parentName:"li"},Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"max_delay")," (string, optional, default to 500ms) - Maximum delay to wait\nbefore retrying the request"),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"give_up_after")," (string, optional, default to 1s) - Maximum delay allowed\nfor retries"))),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"cache")," (object, optional) - Enables caching of incoming tokens",Object(o.b)("ul",{parentName:"li"},Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"enabled")," (bool, optional) - Enable the cache, will use exp time of token to\ndetermine when to evict from cache. Defaults to false."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"ttl")," (string) - Can override the default behaviour of using the token exp\ntime, and specify a set time to live for the token in the cache.")))),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-yaml"},"# Global configuration file oathkeeper.yml\nauthenticators:\n  oauth2_introspection:\n    # Set enabled to true if the authenticator should be enabled and false to disable the authenticator. Defaults to false.\n    enabled: true\n\n    config:\n      introspection_url: https://my-website.com/oauth2/introspection\n      scope_strategy: exact\n      required_scope:\n        - photo\n        - profile\n      target_audience:\n        - example_audience\n      trusted_issuers:\n        - https://my-website.com/\n      pre_authorization:\n        enabled: true\n        client_id: some_id\n        client_secret: some_secret\n        scope:\n          - introspect\n        token_url: https://my-website.com/oauth2/token\n      token_from:\n        header: Custom-Authorization-Header\n        # or\n        # query_parameter: auth-token\n        # or\n        # cookie: auth-token\n      introspection_request_headers:\n        x-forwarded-proto: https\n      retry:\n        max_delay: 300ms\n        give_up_after: 2s\n      cache:\n        enabled: true\n        ttl: 60s\n")),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-yaml"},"# Some Access Rule: access-rule-1.yaml\nid: access-rule-1\n# match: ...\n# upstream: ...\nauthenticators:\n  - handler: oauth2_introspection\n    config:\n      introspection_url: https://my-website.com/oauth2/introspection\n      scope_strategy: exact\n      required_scope:\n        - photo\n        - profile\n      target_audience:\n        - example_audience\n      trusted_issuers:\n        - https://my-website.com/\n      pre_authorization:\n        enabled: true\n        client_id: some_id\n        client_secret: some_secret\n        scope:\n          - introspect\n        token_url: https://my-website.com/oauth2/token\n      token_from:\n        query_parameter: auth-token\n        # or\n        # header: Custom-Authorization-Header\n        # or\n        # cookie: auth-token\n      introspection_request_headers:\n        x-forwarded-proto: https\n        x-foo: bar\n      retry:\n        max_delay: 300ms\n        give_up_after: 2s\n")),Object(o.b)("h3",{id:"access-rule-example-6"},"Access Rule Example"),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-shell"},'$ cat ./rules.json\n\n[{\n  "id": "some-id",\n  "upstream": {\n    "url": "http://my-backend-service"\n  },\n  "match": {\n    "url": "http://my-app/some-route",\n    "methods": [\n      "GET"\n    ]\n  },\n  "authenticators": [{\n    "handler": "oauth2_introspection",\n    "config": {\n      "required_scope": ["scope-a", "scope-b"],\n      "target_audience": ["example_audience"]\n    }\n  }],\n  "authorizer": { "handler": "allow" },\n  "mutators": [{ "handler": "noop" }]\n}]\n\n$ curl -X GET http://my-app/some-route\n\nHTTP/1.0 401 Status Unauthorized\nThe request is not authorized because no credentials have been provided.\n\n$ curl -X GET -H \'Authorization: Bearer invalid-token\' http://my-app/some-route\n\nHTTP/1.0 401 Status Unauthorized\nThe request is not authorized because the provided credentials are invalid.\n\n$ curl -X GET -H \'Authorization: Bearer valid.access.token.from.peter\' http://my-app/some-route\n\nHTTP/1.0 200 OK\nThe request has been allowed! The subject is: "peter"\n')),Object(o.b)("p",null,"In the background, this handler will make a request to the OAuth 2.0 Token\nEndpoint (configuration value\n",Object(o.b)("inlineCode",{parentName:"p"},"authenticators.oauth2_introspection.introspection_url"),") to check if the Bearer\nToken is valid:"),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre"},"POST /oauth2/introspect HTTP/1.1\n\ntoken=valid.access.token.from.peter\n")),Object(o.b)("p",null,"If pre-authorization is enabled, that request will include an Authorization\nHeader:"),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre"},"POST /oauth2/introspect HTTP/1.1\nAuthorization: Bearer token-received-by-performing-pre-authorization\n\ntoken=valid.access.token.from.peter\n")),Object(o.b)("p",null,"The Token is considered valid if the Introspection response is HTTP 200 OK and\nincludes ",Object(o.b)("inlineCode",{parentName:"p"},'{"active":true}')," in the response payload. The subject is extracted\nfrom the ",Object(o.b)("inlineCode",{parentName:"p"},"username")," field."),Object(o.b)("h2",{id:"jwt"},Object(o.b)("inlineCode",{parentName:"h2"},"jwt")),Object(o.b)("p",null,"The ",Object(o.b)("inlineCode",{parentName:"p"},"jwt")," authenticator handles requests that have an Bearer Token in the\nAuthorization Header (",Object(o.b)("inlineCode",{parentName:"p"},"Authorization: bearer <token>"),") or in a different header\nor query parameter specified in configuration. It assumes that the token is a\nJSON Web Token and tries to verify the signature of it."),Object(o.b)("h3",{id:"configuration-7"},"Configuration"),Object(o.b)("ul",null,Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"jwks_urls")," ([]string, required) - The URLs where ORY Oathkeeper can retrieve\nJSON Web Keys from for validating the JSON Web Token. Usually something like\n",Object(o.b)("inlineCode",{parentName:"li"},"https://my-keys.com/.well-known/jwks.json"),". The response of that endpoint\nmust return a JSON Web Key Set (JWKS)."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"scope_strategy"),' (string, optional) - Sets the strategy to be used to\nvalidate/match the scope. Supports "hierarchic", "exact", "wildcard", "none".\nDefaults to "none".'),Object(o.b)("li",{parentName:"ul"},"If ",Object(o.b)("inlineCode",{parentName:"li"},"trusted_issuers")," ([]string) is set, the JWT must contain a value for claim\n",Object(o.b)("inlineCode",{parentName:"li"},"iss")," that matches ",Object(o.b)("em",{parentName:"li"},"exactly")," (case-sensitive) one of the values of\n",Object(o.b)("inlineCode",{parentName:"li"},"trusted_issuers"),". If no values are configured, the issuer will be ignored."),Object(o.b)("li",{parentName:"ul"},"If ",Object(o.b)("inlineCode",{parentName:"li"},"target_audience")," ([]string) is set, the JWT must contain all values\n(exact, case-sensitive) in the claim ",Object(o.b)("inlineCode",{parentName:"li"},"aud"),". If no values are configured, the\naudience will be ignored."),Object(o.b)("li",{parentName:"ul"},"Value ",Object(o.b)("inlineCode",{parentName:"li"},"allowed_algorithms")," ([]string) sets what signing algorithms are\nallowed. Defaults to ",Object(o.b)("inlineCode",{parentName:"li"},"RS256"),"."),Object(o.b)("li",{parentName:"ul"},"Value ",Object(o.b)("inlineCode",{parentName:"li"},"required_scope")," ([]string) validates the scope of the JWT. It will\nchecks for claims ",Object(o.b)("inlineCode",{parentName:"li"},"scp"),", ",Object(o.b)("inlineCode",{parentName:"li"},"scope"),", ",Object(o.b)("inlineCode",{parentName:"li"},"scopes")," in the JWT when validating the\nscope as that claim is not standardized."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"token_from")," (object, optional) - The location of the bearer token. If not\nconfigured, the token will be received from a default location -\n'Authorization' header. One and only one location (header, query, or cookie)\nmust be specified.",Object(o.b)("ul",{parentName:"li"},Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"header")," (string, required, one of) - The header (case insensitive) that\nmust contain a Bearer token for request authentication. It can't be set\nalong with ",Object(o.b)("inlineCode",{parentName:"li"},"query_parameter")," or ",Object(o.b)("inlineCode",{parentName:"li"},"cookie"),"."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"query_parameter")," (string, required, one of) - The query parameter (case\nsensitive) that must contain a Bearer token for request authentication. It\ncan't be set along with ",Object(o.b)("inlineCode",{parentName:"li"},"header")," or ",Object(o.b)("inlineCode",{parentName:"li"},"cookie"),"."),Object(o.b)("li",{parentName:"ul"},Object(o.b)("inlineCode",{parentName:"li"},"cookie")," (string, required, one of) - The cookie (case sensitive) that must\ncontain a Bearer token for request authentication. It can't be set along\nwith ",Object(o.b)("inlineCode",{parentName:"li"},"header")," or ",Object(o.b)("inlineCode",{parentName:"li"},"query_parameter"))))),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-yaml"},"# Global configuration file oathkeeper.yml\nauthenticators:\n  jwt:\n    # Set enabled to true if the authenticator should be enabled and false to disable the authenticator. Defaults to false.\n    enabled: true\n\n    config:\n      jwks_urls:\n        - https://my-website.com/.well-known/jwks.json\n        - https://my-other-website.com/.well-known/jwks.json\n        - file://path/to/local/jwks.json\n      scope_strategy: none\n      required_scope:\n        - scope-a\n        - scope-b\n      target_audience:\n        - https://my-service.com/api/users\n        - https://my-service.com/api/devices\n      trusted_issuers:\n        - https://my-issuer.com/\n      allowed_algorithms:\n        - RS256\n      token_from:\n        header: Custom-Authorization-Header\n        # or\n        # query_parameter: auth-token\n        # or\n        # cookie: auth-token\n")),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-yaml"},"# Some Access Rule: access-rule-1.yaml\nid: access-rule-1\n# match: ...\n# upstream: ...\nauthenticators:\n  - handler: jwt\n    config:\n      jwks_urls:\n        - https://my-website.com/.well-known/jwks.json\n        - https://my-other-website.com/.well-known/jwks.json\n        - file://path/to/local/jwks.json\n      scope_strategy: none\n      required_scope:\n        - scope-a\n        - scope-b\n      target_audience:\n        - https://my-service.com/api/users\n        - https://my-service.com/api/devices\n      trusted_issuers:\n        - https://my-issuer.com/\n      allowed_algorithms:\n        - RS256\n      token_from:\n        query_parameter: auth-token\n        # or\n        # header: Custom-Authorization-Header\n        # or\n        # cookie: auth-token\n")),Object(o.b)("h4",{id:"validation-example"},"Validation example"),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-json"},'{\n  "handler": "jwt",\n  "config": {\n    "required_scope": ["scope-a", "scope-b"],\n    "target_audience": [\n      "https://my-service.com/api/users",\n      "https://my-service.com/api/devices"\n    ],\n    "trusted_issuers": ["https://my-issuer.com/"],\n    "allowed_algorithms": ["RS256", "RS256"]\n  }\n}\n')),Object(o.b)("p",null,"That exemplary Access Rule consider the following (decoded) JSON Web Token as\nvalid:"),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre"},'{\n  "alg": "RS256"\n}\n{\n  "iss": "https://my-issuer.com/",\n  "aud": ["https://my-service.com/api/users", "https://my-service.com/api/devices"],\n  "scp": ["scope-a", "scope-b"]\n}\n')),Object(o.b)("p",null,"And this token as invalid (audience is missing, issuer is not matching, scope is\nmissing, wrong algorithm):"),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre"},'{\n  "alg": "HS256"\n}\n{\n  "iss": "https://not-my-issuer.com/",\n  "aud": ["https://my-service.com/api/users"],\n  "scp": ["not-scope-a", "scope-b"]\n}\n')),Object(o.b)("h3",{id:"scope"},"Scope"),Object(o.b)("p",null,"JSON Web Tokens can be scoped. However, that feature is not standardized and\nseveral claims that represent the token scope have been seen in the wild: ",Object(o.b)("inlineCode",{parentName:"p"},"scp"),",\n",Object(o.b)("inlineCode",{parentName:"p"},"scope"),", ",Object(o.b)("inlineCode",{parentName:"p"},"scopes"),". Additionally, the claim value can be a string (",Object(o.b)("inlineCode",{parentName:"p"},'"scope-a"'),"),\na space-delimited string (",Object(o.b)("inlineCode",{parentName:"p"},'"scope-a scope-b"'),") or a JSON string array\n(",Object(o.b)("inlineCode",{parentName:"p"},'["scope-a", "scope-b"]'),"). Because of this ambiguity, all of those claims are\nchecked and parsed and will be available as ",Object(o.b)("inlineCode",{parentName:"p"},"scp")," (string array) in the\nauthentication session (",Object(o.b)("inlineCode",{parentName:"p"},'.Extra["scp"]'),")."),Object(o.b)("h3",{id:"access-rule-example-7"},"Access Rule Example"),Object(o.b)("pre",null,Object(o.b)("code",{parentName:"pre",className:"language-shell"},'$ cat ./rules.json\n\n[{\n  "id": "some-id",\n  "upstream": {\n    "url": "http://my-backend-service"\n  },\n  "match": {\n    "url": "http://my-app/some-route",\n    "methods": [\n      "GET"\n    ]\n  },\n  "authenticators": [{\n    "handler": "jwt",\n    "config": {\n      "required_scope": ["scope-a", "scope-b"],\n      "target_audience": ["aud-1"],\n      "trusted_issuers": ["iss-1"]\n    }\n  }],\n  "authorizer": { "handler": "allow" },\n  "mutators": [{ "handler": "noop" }]\n}]\n\n$ curl -X GET http://my-app/some-route\n\nHTTP/1.0 401 Status Unauthorized\nThe request is not authorized because no credentials have been provided.\n\n$ curl -X GET -H \'Authorization: Bearer invalid-token\' http://my-app/some-route\n\nHTTP/1.0 401 Status Unauthorized\nThe request is not authorized because the provided credentials are invalid.\n\n$ curl -X GET -H \'Authorization: Bearer valid.jwtfrom.peter\' http://my-app/some-route\n\nHTTP/1.0 200 OK\nThe request has been allowed! The subject is: "peter"\n')),Object(o.b)("p",null,"In the background, this handler will fetch all JSON Web Key Sets provided by\nconfiguration key ",Object(o.b)("inlineCode",{parentName:"p"},"authenticators.jwt.jwks_urls")," and use those keys to verify\nthe signature. If the signature can not be verified by any of those keys, the\nJWT is considered invalid."))}u.isMDXComponent=!0}}]);