summaryrefslogtreecommitdiff
path: root/doc/run-identity/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/run-identity/README.md')
-rw-r--r--doc/run-identity/README.md209
1 files changed, 172 insertions, 37 deletions
diff --git a/doc/run-identity/README.md b/doc/run-identity/README.md
index 8587512..a83929d 100644
--- a/doc/run-identity/README.md
+++ b/doc/run-identity/README.md
@@ -23,10 +23,9 @@ Related Field Requests:
To Learn:
-* [ ] the OIDC flows.
-* [ ] the Vault API.
-* [ ] the key material available to a Terraform run context.
-
+* [X] the OIDC flows.
+* [X] the Vault API.
+* [X] the key material available to a Terraform run context.
1. In cloud provider, create OIDC trust between cloud role and TFC Workspace.
1. In run task, generate a token via OIDC Provider before apply step.
@@ -34,40 +33,174 @@ To Learn:
```plaintext
-Is it like this?
- ------- ---------------- ----------
- | TFC | | OIDC Provider| | runner |
- ------- ---------------- ----------
- | | |
- |--- request token ----->| |
- | | |
- |<----- return token ----| |
- | |
- | |
- | |
- |---- inject secrets ---------------------->|
-
-or like this ...
-
- ------- ---------- ---------
- | TFC | | Runner | | Vault |
- ------- ---------- ---------
- * aws access/secret
- -------->
- * job description
- * a way to get key material from Vault. (token)
- * config version data.
- --------> give me the secrets
- * do the thing
- <------- return the job status
-
-1. schedule run of apply.
-2. key material to do the apply.
- * aws access/secret key
- * environment vars
-3. low ttl key material to do the things.
+ |<--- 1. fetch .well-known/openid-configuration
+ | |
+ |---- 2. return public keys ------->|
+ | |
+ ------- ---------------- ---------- ---------------------
+ | TFC | | OIDC Provider| | runner | | AWS/Azure/GCP/Vault |
+ ------- ---------------- ---------- ---------------------
+ | | | |
+ |- 3. request id token ->| | |
+ | | | |
+ |<-4. return id token ---| | |
+ | | |
+ |>--5. provide id token ------------------------------------>|
+ | |
+ |<---6. return secrets ------------------------------------<|
+ | | |
+ |---7. inject secrets ------------------->| |
+ | |
+ |-- 8. do things ->|
```
+1. the identity provider is registered with AWS/Azure/GCP/Vault.
+ * the `/.well-known/openid-configuration` endpoint is used to fetch metadata.
+2. the openid metadata is returned.
+ * this metadata is used to validate the integrity of JWT's that it receives in step 5.
+ ```bash
+ モ curl https://dev-klipadbq.us.auth0.com/.well-known/openid-configuration | jq
+ {
+ "issuer": "https://dev-klipadbq.us.auth0.com/",
+ "authorization_endpoint": "https://dev-klipadbq.us.auth0.com/authorize",
+ "token_endpoint": "https://dev-klipadbq.us.auth0.com/oauth/token",
+ "device_authorization_endpoint": "https://dev-klipadbq.us.auth0.com/oauth/device/code",
+ "userinfo_endpoint": "https://dev-klipadbq.us.auth0.com/userinfo",
+ "mfa_challenge_endpoint": "https://dev-klipadbq.us.auth0.com/mfa/challenge",
+ "jwks_uri": "https://dev-klipadbq.us.auth0.com/.well-known/jwks.json",
+ "registration_endpoint": "https://dev-klipadbq.us.auth0.com/oidc/register",
+ "revocation_endpoint": "https://dev-klipadbq.us.auth0.com/oauth/revoke",
+ "scopes_supported": [
+ "openid",
+ "profile",
+ "offline_access",
+ "name",
+ "given_name",
+ "family_name",
+ "nickname",
+ "email",
+ "email_verified",
+ "picture",
+ "created_at",
+ "identities",
+ "phone",
+ "address"
+ ],
+ "response_types_supported": [
+ "code",
+ "token",
+ "id_token",
+ "code token",
+ "code id_token",
+ "token id_token",
+ "code token id_token"
+ ],
+ "code_challenge_methods_supported": [
+ "S256",
+ "plain"
+ ],
+ "response_modes_supported": [
+ "query",
+ "fragment",
+ "form_post"
+ ],
+ "subject_types_supported": [
+ "public"
+ ],
+ "id_token_signing_alg_values_supported": [
+ "HS256",
+ "RS256"
+ ],
+ "token_endpoint_auth_methods_supported": [
+ "client_secret_basic",
+ "client_secret_post"
+ ],
+ "claims_supported": [
+ "aud",
+ "auth_time",
+ "created_at",
+ "email",
+ "email_verified",
+ "exp",
+ "family_name",
+ "given_name",
+ "iat",
+ "identities",
+ "iss",
+ "name",
+ "nickname",
+ "phone_number",
+ "picture",
+ "sub"
+ ],
+ "request_uri_parameter_supported": false
+ }
+ ```
+3. TFC starts a plan, apply etc. by requesting (generating?) an `id_token`
+ * `id_token` can be obtained via an authz code flow, implicit flow or hybrid flow.
+ ```bash
+ curl -s \
+ -u "client_id:client_secret" \
+ --basic \
+ -d "grant_type=authorization_code&code=example&redirect_uri=http://localhost:3000/oauth/callback" \
+ "https://dev-klipadbq.us.auth0.com/oauth/token"
+ ```
+4. the `id_token` that is returned is a signed JWT
+ * signature is a hash of content encrypted with private key.
+ * signature can be decrypted by public key found in metadata exchange.
+ * hash is recomputed by aws to ensure that the data hasn't been tampered with.
+ ```json
+ {
+ "access_token":"eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIiwiaXNzIjoiaHR0cHM6Ly9kZXYta2xpcGFkYnEudXMuYXV0aDAuY29tLyJ9..kpYUjY8jDc2kRVat.noMdBQplkqhibQhYsz5pWr84Y9KkYl5XsS4IPQhq0EOa0nsy7tqAyH0viGKsFNZ2qxnckE2qk7YqDPGsbgSR_pQlsxGODllWEjVxhRRSDehHkWf9h5rBsMS0bVPbHRbRp_z9hSmzXdtd3xRWHgMN35tu3cylRqnWLgp4bVZF8UA4sEPHe6wZFWrkPq_YCYhTDGoFsxk-6WXy4_r6xKIttWeXKEA0bTADsERKBTfRNI5F7F4-iTHd9VQl4HItoRfDz48cp86LD1AiuES-mMtPgP9HaWbqo9O4UDk9NXs_awhKfyNy.uNjG1xpLDnc4Km9oHcFwNg",
+ "id_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlE2T2V2XzZTMkhDa3VKVFdQNzlrdCJ9.eyJpc3MiOiJodHRwczovL2Rldi1rbGlwYWRicS51cy5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NjI1NjM4ODhmN2YwZjUwMDY4M2Y3YTllIiwiYXVkIjoieW1oaDF0clo4VGNxVVBqM1hlWm96MjdLalhQaEFtaE8iLCJpYXQiOjE2NDk4MjMxNTMsImV4cCI6MTY0OTg1OTE1M30.R_zm-f2e6ZVKW73ycPXbBtoBk8gGNytiol4ET4RtNTmgTElFHNDUmyHJDTJbzyHACOju5RcR4o0kpwxdkCmZy7iQw1U4JphAhb1Na4wKHJqk7zn1wJ-hrHou7QGnuVufQTvLnxyxcF6AMc5gxi3CbQf1p5NH0JQpdgc7R-tiQDMV4sa7mWMdVVNHv7oIJFu7PKuPKkg9Aox71dtq-e5_Ucth7JNkDHV61xvJ3L6UoPk9BVDqj4pT84T_ucfKsREdS-_6_2vTneDycxl1UW7_e3UTXpvsaui87LKSBs4L2feOuWTxRL62-XKN--D02tLY6nLdu-OAFEnLy1NX8h0qqA",
+ "scope":"openid",
+ "expires_in":86400,
+ "token_type":"Bearer"
+ }
+ ```
+ ```irb
+ irb(main):001:0> require 'base64'
+ irb(main):002:0> x = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlE2T2V2XzZTMkhDa3VKVFdQNzlrdCJ9.eyJpc3MiOiJodHRwczovL2Rldi1rbGlwYWRicS51cy5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NjI1NjM4ODhmN2YwZjUwMDY4M2Y3YTllIiwiYXVkIjoieW1oaDF0clo4VGNxVVBqM1hlWm96MjdLalhQaEFtaE8iLCJpYXQiOjE2NDk4MjMxNTMsImV4cCI6MTY0OTg1OTE1M30.R_zm-f2e6ZVKW73ycPXbBtoBk8gGNytiol4ET4RtNTmgTElFHNDUmyHJDTJbzyHACOju5RcR4o0kpwxdkCmZy7iQw1U4JphAhb1Na4wKHJqk7zn1wJ-hrHou7QGnuVufQTvLnxyxcF6AMc5gxi3CbQf1p5NH0JQpdgc7R-tiQDMV4sa7mWMdVVNHv7oIJFu7PKuPKkg9Aox71dtq-e5_Ucth7JNkDHV61xvJ3L6UoPk9BVDqj4pT84T_ucfKsREdS-_6_2vTneDycxl1UW7_e3UTXpvsaui87LKSBs4L2feOuWTxRL62-XKN--D02tLY6nLdu-OAFEnLy1NX8h0qqA'
+ => "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlE2T2V2XzZTMkhDa3VKVFdQNzlrdCJ9.eyJpc3MiOiJodHRwczovL2Rldi1rbGlwYWRicS51cy5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NjI1NjM4ODhmN2YwZjUwMDY4M2Y3YTllIiwiYXVkIjoieW1oaDF0clo4VGNxVVBqM1hlWm96MjdLalhQaEFtaE8iLCJpYXQiOjE2NDk4MjMxNTMsImV4cCI6MTY0OTg1OTE1M...
+ irb(main):003:0> x.split('.')
+ =>
+ ["eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlE2T2V2XzZTMkhDa3VKVFdQNzlrdCJ9",
+ "eyJpc3MiOiJodHRwczovL2Rldi1rbGlwYWRicS51cy5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NjI1NjM4ODhmN2YwZjUwMDY4M2Y3YTllIiwiYXVkIjoieW1oaDF0clo4VGNxVVBqM1hlWm96MjdLalhQaEFtaE8iLCJpYXQiOjE2NDk4MjMxNTMsImV4cCI6MTY0OTg1OTE1M30",
+ "R_zm-f2e6ZVKW73ycPXbBtoBk8gGNytiol4ET4RtNTmgTElFHNDUmyHJDTJbzyHACOju5RcR4o0kpwxdkCmZy7iQw1U4JphAhb1Na4wKHJqk7zn1wJ-hrHou7QGnuVufQTvLnxyxcF6AMc5gxi3CbQf1p5NH0JQpdgc7R-tiQDMV4sa7mWMdVVNHv7oIJFu7PKuPKkg9Aox71dtq-e5_Ucth7JNkDHV61xvJ3L6UoPk9BVDqj4pT84T_ucfKsREdS-_6_2vTneDycxl1UW7_e3UTXpvsaui87LKSBs4L2feOuWTxRL62-XKN--D02tLY6nLdu-OAFEnLy1NX8h0qqA"]
+ irb(main):004:0> Base64.decode64(x.split('.')[0])
+ => "{\"alg\":\"RS256\",\"typ\":\"JWT\",\"kid\":\"Q6Oev_6S2HCkuJTWP79kt\"}"
+ irb(main):005:0> Base64.decode64(x.split('.')[1])
+ => "{\"iss\":\"https://dev-klipadbq.us.auth0.com/\",\"sub\":\"auth0|62563888f7f0f500683f7a9e\",\"aud\":\"ymhh1trZ8TcqUPj3XeZoz27KjXPhAmhO\",\"iat\":1649823153,\"exp\":1649859153}"
+ ```
+5. TFC sends the `id_token` to the token service for the cloud provider. e.g. [STS][1]
+ ```bash
+ モ aws sts assume-role-with-web-identity \
+ --role-arn "arn:aws:iam::119201842733:role/idp-web-identity-role" \
+ --role-session-name="example-1" \
+ --duration-seconds 3600 \
+ --web-identity-token="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlE2T2V2XzZTMkhDa3VKVFdQNzlrdCJ9.eyJpc3MiOiJodHRwczovL2Rldi1rbGlwYWRicS51cy5hdXRoMC5jb20vIiwic3ViIjoiYXV0aDB8NjI1NjM4ODhmN2YwZjUwMDY4M2Y3YTllIiwiYXVkIjoieW1oaDF0clo4VGNxVVBqM1hlWm96MjdLalhQaEFtaE8iLCJpYXQiOjE2NDk4MjMxNTMsImV4cCI6MTY0OTg1OTE1M30.R_zm-f2e6ZVKW73ycPXbBtoBk8gGNytiol4ET4RtNTmgTElFHNDUmyHJDTJbzyHACOju5RcR4o0kpwxdkCmZy7iQw1U4JphAhb1Na4wKHJqk7zn1wJ-hrHou7QGnuVufQTvLnxyxcF6AMc5gxi3CbQf1p5NH0JQpdgc7R-tiQDMV4sa7mWMdVVNHv7oIJFu7PKuPKkg9Aox71dtq-e5_Ucth7JNkDHV61xvJ3L6UoPk9BVDqj4pT84T_ucfKsREdS-_6_2vTneDycxl1UW7_e3UTXpvsaui87LKSBs4L2feOuWTxRL62-XKN--D02tLY6nLdu-OAFEnLy1NX8h0qqA" --output json | cat
+ ```
+6. Cloud provider returns secrets.
+ ```json
+ {
+ "Credentials": {
+ "AccessKeyId": "ASIARXQH3YYWQMPAN57M",
+ "SecretAccessKey": "nRDvl9q6xoDtvLhha16mOQse9r03XoL2Yw6yMtwp",
+ "SessionToken": "FwoGZXIvYXdzEL7//////////wEaDCdzgBb1TNJKqqghGSLXAim8vKlHEDn/MxcIsIWnPloA+muPpcvh27zTlKg0XOAVHP6gHudFZHtHJY3L6Lnisf6np/7rstaHqGQy6Fa9tr47KHZtkhQRaDcrpKMgGc9v3VqP4g72k3NNg2zgzWThJEfvNge/RyabpIY1oqju9rK9CS3I7y8ntW4e/8KTxeYIniWgAPBrFJlnDm+vahTtsg/04OkuL+iIpfI+FaUBzTdzZGaE3cKztJX1e/0NpmOGLx5HCkaF0tn9MeZBeSJ/Z/pF4fAZK12+uN0pLvZOkMta+lFhMWlbzqF6pPiruF6PUv6iGILyE85JA/uM6ZerV3RiF4YdxyO5NOnq4USRzdxLQq9IqD5aZNeT1ZnbDPZR4yhztni01t6MB5DtXpaweRdFGEK/cT0aquOGYjYs6qVjuZOnqrUdObBk/V9R9TYuhur2StzyWeXozWSehfr/j/qovO39y1Mo9J3ZkgYyJArNFYwaGf/X2emoBDq/Jl5V2hEiFxANPW7LAhquWzIwIjDQBA==",
+ "Expiration": "2022-04-13T05:17:56+00:00"
+ },
+ "SubjectFromWebIdentityToken": "auth0|62563888f7f0f500683f7a9e",
+ "AssumedRoleUser": {
+ "AssumedRoleId": "AROARXQH3YYWSI3UUY4XD:example-1",
+ "Arn": "arn:aws:sts::119201842733:assumed-role/idp-web-identity-role/example-1"
+ },
+ "Provider": "arn:aws:iam::119201842733:oidc-provider/dev-klipadbq.us.auth0.com/",
+ "Audience": "ymhh1trZ8TcqUPj3XeZoz27KjXPhAmhO"
+ }
+ ```
+7. TFC injects secrets into the `Run`. I don't know how. Config variables, maybe?
+8. The `Run` makes API calls to the cloud provider using the `AWS_ACCESS_KEY_ID` and`AWS_SECRET_KEY` env vars that were injected.
+
# Vault
Start the server:
@@ -151,5 +284,7 @@ Acceptance Criteria:
To think about:
1. NTP syncronization to ensure time matches from client to server.
+1. X.509 certificate expiration management?
1. Who is on the app-sec team? (Brian?)
-1. x.509 certificate expiration.
+
+[1]: https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRoleWithWebIdentity.html