troubleshooting X-Access-Token not send to backend service (Okta, oauth2 flow, envoy, eas)
See original GitHub issueHello,
with help managed to run Oauth2 flow with Okta. Integration with EAS is done via “envoy.extensions.filters.http.ext_authz.v3.ExtAuthz”.
All is woking now and decided to add “envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication” and “envoy.extensions.filters.http.rbac” to be able to implement RBAC based on group claims in JWT tokens.
As i understood EAS is capable to obtain JWT tokens and populate to request headers, ie “X-Access-Token” or “Authorization”.
For some reason (probably envoy configuration) “X-Access-Token” is not set. Searching through EAS logs i see request to “/envoy/verify-params-header/” endpoint and if i interpreter that correctly, the response is 200 and appropriate headers are set, ie. “X-Access-Token”.
debug: plugin response {"statusCode":200,"statusMessage":"","body":"","cookies":[],"clearCookies":[],"headers":{"X-Access-Token":"eyJraW
If i look into connection flow from client side, i see no requests to “/envoy/verify-params-header/” endpoint. So im assuming it is “envoy.extensions.filters.http.ext_authz.v3.ExtAuthz” interacting with EAS.
Now the question. How does this really work? How and than “X-Access-Token” is set? As i cannot understand why “X-Access-Token” is not sent (or removed, etc.) to backend service (upstream in envoy§s terminology).
Thank you!
generate_config_token.js:
const jwt = require("jsonwebtoken");
const utils = require("../src/utils");
const config_token_sign_secret =
process.env.EAS_CONFIG_TOKEN_SIGN_SECRET ||
utils.exit_failure("missing EAS_CONFIG_TOKEN_SIGN_SECRET env variable");
const config_token_encrypt_secret =
process.env.EAS_CONFIG_TOKEN_ENCRYPT_SECRET ||
utils.exit_failure("missing EAS_CONFIG_TOKEN_ENCRYPT_SECRET env variable");
let config_token = {
/**
* future feature: allow blocking certain token IDs
*/
//jti: <some known value>
/**
* using the same aud for multiple tokens allows sso for all services sharing the aud
*/
aud: "aud_or_client_id", //should be unique to prevent cookie/session hijacking, defaults to a hash unique to the whole config
eas: {
// list of plugin definitions, refer to PLUGINS.md for details
plugins: [
{
type: "oauth2",
issuer: {
authorization_endpoint: "https://zztop.oktapreview.com/oauth2/authorization_server/v1/authorize",
token_endpoint: "https://zztop.oktapreview.com/oauth2/authorization_server/v1/token"
},
client: {
client_id: "aud_or_client_id",
client_secret: "client_secret"
},
scopes: ["user"],
/**
* static redirect URI
* if your oauth provider does not support wildcards place the URL configured in the provider (that will return to this proper service) here
*/
redirect_uri: "https://localhost7:10443/oauth/callback",
features: {
/**
* if false cookies will be 'session' cookies
* if true and cookies expire will expire with tokens
*/
cookie_expiry: false,
userinfo_expiry: 86400, // 24 hours
/**
* sessions become a floating window *if* tokens are being refreshed or userinfo being refreshed
*/
session_expiry: 604800, // 7 days
/**
* if session_expiry is a number and this is set then sessions become a 'floating window'
* if activity is triggered in this amount of time *before* preceeding the end of the
* session then the expiration time is extended + session_expiry
*/
session_expiry_refresh_window: 86400, // 24 hours
/**
* will re-use the same id (ie: same cookie) for a particular client if a session has expired
*/
session_retain_id: true,
/**
* if the access token is expired and a refresh token is available, refresh
*/
refresh_access_token: true,
/**
* fetch userinfo and include as X-Userinfo header to backing service
*/
fetch_userinfo: false,
userinfo: {
provider: "oidc",
config: {
fetch_teams: true,
fetch_organizations: true,
fetch_emails: true
}
},
/**
* which token (if any) to send back to the proxy as the Authorization Bearer value
* note the proxy must allow the token to be passed to the backend if desired
*
* possible values are access_token, or refresh_token
*/
authorization_token: "access_token"
},
assertions: {
/**
* assert the token(s) has not expired
*/
exp: true
},
cookie: {
name: "_eas_localhost_session_", //default is _oeas_oauth_session
//domain: "localhost" //defaults to request domain, could do sso with more generic domain
//path: "/",
}
}
]
}
};
config_token = jwt.sign(config_token, config_token_sign_secret);
const config_token_encrypted = utils.encrypt(
config_token_encrypt_secret,
config_token
);
//console.log("token: %s", config_token);
//console.log("");
console.log("encrypted token (for server-side usage): %s", config_token_encrypted);
console.log("");
console.log(
"URL safe config_token: %s",
encodeURIComponent(config_token_encrypted)
);
console.log("");
ExtAuthz config:
http_filters:
- name: envoy.filters.http.ext_authz
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
transport_api_version: V3
http_service:
authorizationRequest:
allowedHeaders:
patterns:
- exact: cookie
- exact: X-Forwarded-Host
- exact: X-Forwarded-Method
- exact: X-Forwarded-Proto
- exact: X-Forwarded-Uri
headers_to_add:
- key: "x-eas-verify-params"
value: '{"config_token":"---reducted---"}'
- key: X-Forwarded-Proto
value: "https"
pathPrefix: /envoy/verify-params-header
serverUri:
cluster: eas
timeout: 2.25s
uri: http://eas:8080
- name: envoy.filters.http.router
Issue Analytics
- State:
- Created 2 years ago
- Comments:12 (5 by maintainers)

Top Related StackOverflow Question
Actually, I spoof
x-forwarded-uriandx-forwarded-methodinternally in the case ofenvoyso those 2 may not be actually getting sent. Sorry, forgot to mention that earlier. I do that to make the internals ofeasbehave the same as other proxies. The wayenvoyhandles things is slightly different that some of the others (hence the special endpoint just forenvoysetups).The above doesn’t explain the missing
-protoheader though.I made updated “x-forwarded-proto” to lower case instead of “X-Forwarded-Proto” as you suggested, and it seems to help:
Ill trace it tomorrow to double check, as strangely other parameters work. Have to go to sleep, as work day tomorrow.
Thank you for great project and help!