Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Environment variables #180

Open
gfrankliu opened this issue Jul 25, 2023 · 12 comments
Open

Environment variables #180

gfrankliu opened this issue Jul 25, 2023 · 12 comments

Comments

@gfrankliu
Copy link

The docker example in the README mentions bunch of environment variables.

docker run -d --name eas -p 8080:8080 \
-e EAS_CONFIG_TOKEN_SIGN_SECRET="foo" \
-e EAS_CONFIG_TOKEN_ENCRYPT_SECRET="bar" \
-e EAS_ISSUER_SIGN_SECRET="super secret" \
-e EAS_ISSUER_ENCRYPT_SECRET="blah" \
-e EAS_COOKIE_SIGN_SECRET="hello world" \
-e EAS_COOKIE_ENCRYPT_SECRET="something" \
-e EAS_SESSION_ENCRYPT_SECRET="baz" \
-e EAS_CONFIG_TOKEN_STORES='{}' \
-e EAS_LOG_LEVEL="info" \
-e EAS_PORT=8080 \
travisghansen/external-auth-server

Is there a doc explaining those? I assume some of them are used only by some plugins. So if I don't use those plugins, I could just not set, or give some dummy values.

@travisghansen
Copy link
Owner

Good point. I didn’t realize those never got documented properly.

The CONFIG_ are required for everything. The issuer/cookie/session stuff is currently only for oauth/oidc use. Having said that, the deployment checks for the env vars at startup to ensure the service is fully functional as it has no knowledge of config tokens at startup.

@gfrankliu
Copy link
Author

What's the different use for SIGN_SECRET and ENCRYPT_SECRET? Do we need both for everything? eg: oauth2-proxy only uses a single --cookie-secret to encrypt/decrypt cookies.

@travisghansen
Copy link
Owner

travisghansen commented Jul 25, 2023

Here's the breakdown:

  • EAS_CONFIG_TOKEN_SIGN_SECRET - used to check the signature of config_tokens (ensure operators cannot just created arbitrary config tokens to be used by the service)
  • EAS_CONFIG_TOKEN_ENCRYPT_SECRET - used to decrypt config_tokens (I require these to be encrypted because the project was designed with separation of duties in mind. For example it may be a security or compliance team creating the config_tokens and they are encrypted because they very likely contain sensitive/secret data...Keeps config_token data hidden from operators.).
  • EAS_ISSUER_SIGN_SECRET - used to sign oauth state data that goes to the IDP/Authorization Server
  • EAS_ISSUER_ENCRYPT_SECRET - used to encrypt state data so end users cannot decipher potentially sensitive data
  • EAS_COOKIE_SIGN_SECRET - used to sign cookies
  • EAS_COOKIE_ENCRYPT_SECRET - used to encrypt cookie data (again to prevent end-users from deciphering any potentially sensitive data)
  • EAS_SESSION_ENCRYPT_SECRET - used to encrypt session data 'at rest', typically sessions are stored in redis so this prevents anyone with direct access to redis from being able to decipher data

oauth2-proxy is a very different approach to the same problem and has far few features. It's limitations are one of the prime reasons I wrote this. In order to keep everything nice and secure and to handle/offload a bunch of features client-side to a mostly stateless service required a lot of signing and encrypting and using different keys for the different attack vectors to keep the blast radius low should something be compromised :)

@gfrankliu
Copy link
Author

Thanks for keeping security in mind!
Have you tried enabling the github dependabot for this repo? It can find if any dependent packages in package.json or yarn.lock, with versions that have vulnerabilities.

@gfrankliu
Copy link
Author

In one of my m2m use case, I use jwt plugin and all requests will come with jwt header:

eas:
  plugins:
    - type: jwt
      header_name: my-jwt-header
      config:
        secret: https://www.provider1.com/public_key-jwk.json
        options:
          audience: /special/audience/for/me
          issuer: https://www.provider1.com

In this case, I guess there are no cookie, sign/encrypt secrets needed, so I can just set those env variables to dummy values?

@travisghansen
Copy link
Owner

Yeah, but you should not need a new deployment per app if that concept was not clear. It's designed to have a single installation to handle many many configs/apps.

@gfrankliu
Copy link
Author

That makes sense.
One additional question regarding the jwt config:

      config:
        secret: https://www.provider1.com/public_key-jwk.json

Is this key cached? If so, for how long? Is this configurable. I see there is "expiresIn" option in this doc but not sure if that is related to this key caching. The provider may update/rotate this key, though infrequent, which will cause jwt validation failure. Will you re-retrieve the key and try again in that case, or will you always re-retrieve this file and update in-memory cache at some pre-defined internal?

@travisghansen
Copy link
Owner

Sorry, been super busy. So the key is cached yes and it's based on the header sent by the provider. In short it will 'just work'.

@gfrankliu
Copy link
Author

I checked the key from iap :

curl -I https://www.gstatic.com/iap/verify/public_key-jwk
HTTP/2 200 
accept-ranges: bytes
content-security-policy: require-trusted-types-for 'script'; report-uri https://csp.withgoogle.com/csp/cloud-gatekeeper-team
cross-origin-resource-policy: cross-origin
cross-origin-opener-policy: same-origin; report-to="cloud-gatekeeper-team"
report-to: {"group":"cloud-gatekeeper-team","max_age":2592000,"endpoints":[{"url":"https://csp.withgoogle.com/csp/report-to/cloud-gatekeeper-team"}]}
content-length: 1352
x-content-type-options: nosniff
server: sffe
x-xss-protection: 0
date: Fri, 28 Jul 2023 15:06:26 GMT
expires: Fri, 28 Jul 2023 15:56:26 GMT
cache-control: public, max-age=3000
last-modified: Fri, 28 Jul 2023 13:40:55 GMT
content-type: application/json
vary: Accept-Encoding
age: 1023
alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000

Does this mean you will cache it for max-age=3000 or until expires: Fri, 28 Jul 2023 15:56:26 GMT ?

@travisghansen
Copy link
Owner

https://github.com/auth0/node-jwks-rsa/blob/master/EXAMPLES.md#caching

I want to say that doc has changed from what it was the last time I looked at it so it may be slightly different. The documented behavior there (which may not be the same version currently imported into the app) seems to indicated a static value defaulting to 10m. I was under the impression the older versions were using one of those 2 headers but don't recall which.

@gfrankliu
Copy link
Author

Yeah, but you should not need a new deployment per app if that concept was not clear. It's designed to have a single installation to handle many many configs/apps.

My understanding is each request to the nginx ingress will trigger a call to external-auth-server. I plan to have one external-auth-server installation for each Kubernetes cluster (nginx ingress) where clusters are scattered across the world, so that auth traffic are local within the cluster. Having all clusters passing every request to a central external-auth-server installation may not be optimal. That's why I am hoping to see oauth plugin supports redirect_uri with uri only without base dns name. The base dns name could be retrieved to $host header if not provided in the redirect_uri config.

@travisghansen
Copy link
Owner

Yeah fair enough. The context of that comment was more about multiple apps within a single cluster.

I can look into making the value of that property a handlebars template.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants