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

[DOM-47678] Add Keycloak service account token support for image builds #101

Closed
wants to merge 4 commits into from

Conversation

ddl-ebrown
Copy link
Contributor

@ddl-ebrown ddl-ebrown commented Jun 13, 2023

Described in https://docs.google.com/document/d/1LXl0aUKAZk9jpnKKGZZxrw3VFRxjAdLqa2WZriSj6Fc/edit as Add Keycloak token acquisition support to Hephaestus

Image is consumable at https://github.com/dominodatalab/hephaestus/pkgs/container/hephaestus/103580396?tag=pr-101

Testing in a real deploy via cli invocation like

helm upgrade hephaestus oci://ghcr.io/dominodatalab/helm/hephaestus --version 0.0.0-pr-101 --debug --namespace domino-compute --values dev-values.yaml --reuse-values

And a dev-values.yaml config like

keycloak:
  enabled: true
  server: http://keycloak-http.domino-platform/auth/
  realm: DominoRealm
  clientId: domino-play
  clientSecret: <redacted>

controller:
  manager:
    image:
      registry: ghcr.io
      repository: dominodatalab/hephaestus
      pullPolicy: Always
      tag: "pr-101"
  podLabels:
    keycloak-client: "true"

Inside of Domino, there is an environment defined like:

  • Base FROM set to docker.io/library/alpine:latest
  • Dockerfile defined like
ARG SERVICE_TOKEN
RUN echo "Injected ARG SERVICE_TOKEN: ${SERVICE_TOKEN}"

Initial implementation verification

Build succeeded at https://mldemo4507.train-sandbox.domino.tech/environments/64920eb0bb2e9b737895a5b6/revisions/649396a7bb2e9b737895a5f5/build/649396a7bb2e9b737895a5f7/logs

Jun 21 2023 17:32:39 -0700 | Validating registry credentials |   |   |  
-- | -- | -- | -- | --
Jun 21 2023 17:32:40 -0700 | Leasing buildkit worker |   |   |  
Jun 21 2023 17:35:52 -0700 | Confirming buildkitd connectivity |   |   |  
Jun 21 2023 17:35:52 -0700 | Buildkitd connectivity established |   |   |  
Jun 21 2023 17:35:52 -0700 | Fetching remote context |   |   |  
Jun 21 2023 17:35:52 -0700 | #1 [internal] load build definition from Dockerfile |   |   |  
Jun 21 2023 17:35:52 -0700 | #1 transferring dockerfile: 199B done |   |   |  
Jun 21 2023 17:35:52 -0700 | #1 DONE 0.0s |   |   |  
Jun 21 2023 17:35:52 -0700 |   |   |   |  
Jun 21 2023 17:35:52 -0700 | #2 [internal] load .dockerignore |   |   |  
Jun 21 2023 17:35:52 -0700 | #2 transferring context: 2B done |   |   |  
Jun 21 2023 17:35:52 -0700 | #2 DONE 0.0s |   |   |  
Jun 21 2023 17:35:52 -0700 |   |   |   |  
Jun 21 2023 17:35:52 -0700 | #3 [internal] load metadata for docker.io/library/alpine:latest |   |   |  
Jun 21 2023 17:35:53 -0700 | #3 DONE 0.8s |   |   |  
Jun 21 2023 17:35:53 -0700 |   |   |   |  
Jun 21 2023 17:35:53 -0700 | #4 [internal] load build context |   |   |  
Jun 21 2023 17:35:53 -0700 | #4 transferring context: 201B done |   |   |  
Jun 21 2023 17:35:53 -0700 | #4 DONE 0.0s |   |   |  
Jun 21 2023 17:35:53 -0700 |   |   |   |  
Jun 21 2023 17:35:53 -0700 | #5 [1/4] FROM docker.io/library/alpine:latest@sha256:82d1e9d7ed48a7523bdebc18cf6290bdb97b82302a8a9c27d4fe885949ea94d1 |   |   |  
Jun 21 2023 17:35:53 -0700 | #5 resolve docker.io/library/alpine:latest@sha256:82d1e9d7ed48a7523bdebc18cf6290bdb97b82302a8a9c27d4fe885949ea94d1 |   |   |  
Jun 21 2023 17:35:53 -0700 | #5 resolve docker.io/library/alpine:latest@sha256:82d1e9d7ed48a7523bdebc18cf6290bdb97b82302a8a9c27d4fe885949ea94d1 0.0s done |   |   |  
Jun 21 2023 17:35:53 -0700 | #5 CACHED |   |   |  
Jun 21 2023 17:35:53 -0700 |   |   |   |  
Jun 21 2023 17:35:53 -0700 | #6 [2/4] RUN echo "Injected ARG SERVICE_TOKEN: <redacted>" |   |   |  
Jun 21 2023 17:35:53 -0700 | #0 0.100 Injected ARG SERVICE_TOKEN: <redacted> |   |   |  
Jun 21 2023 17:35:53 -0700 |   |   |   |  
Jun 21 2023 17:35:53 -0700 | #6 DONE 0.1s |   |   |  
Jun 21 2023 17:35:53 -0700 |   |   |   |  
Jun 21 2023 17:35:53 -0700 | #7 [3/4] RUN echo "Main Dockerfile finished" |   |   |  
Jun 21 2023 17:35:53 -0700 | #0 0.069 Main Dockerfile finished |   |   |  
Jun 21 2023 17:35:53 -0700 |   |   |   |  
Jun 21 2023 17:35:53 -0700 | #7 DONE 0.1s |   |   |  
Jun 21 2023 17:35:53 -0700 |   |   |   |  
Jun 21 2023 17:35:53 -0700 | #8 [4/4] ADD files / |   |   |  
Jun 21 2023 17:35:53 -0700 | #8 DONE 0.0s |   |   |  
Jun 21 2023 17:35:53 -0700 |   |   |   |  
Jun 21 2023 17:35:53 -0700 | #9 exporting to image |   |   |  
Jun 21 2023 17:35:53 -0700 | #9 exporting layers |   |   |  
Jun 21 2023 17:35:53 -0700 | #9 exporting layers 0.1s done |   |   |  
Jun 21 2023 17:35:53 -0700 | #9 exporting manifest sha256:c0c3caa8e2a9ebee70c87fe45cd0bb431e996895ad9aa95557ac0ca9b21a06fb 0.0s done |   |   |  
Jun 21 2023 17:35:53 -0700 | #9 exporting config sha256:26cd972d00ffe631868a693e9ec4a21934d9add8e206f1d9226e98f4c66f7989 0.0s done |   |   |  
Jun 21 2023 17:35:53 -0700 | #9 pushing layers |   |   |  
Jun 21 2023 17:35:55 -0700 | #9 pushing layers 1.7s done |   |   |  
Jun 21 2023 17:35:55 -0700 | #9 pushing manifest for 172.20.88.105:5000/dominodatalab/environment:64920eb0bb2e9b737895a5b6-22@sha256:c0c3caa8e2a9ebee70c87fe45cd0bb431e996895ad9aa95557ac0ca9b21a06fb |   |   |  
Jun 21 2023 17:35:56 -0700 | #9 pushing manifest for 172.20.88.105:5000/dominodatalab/environment:64920eb0bb2e9b737895a5b6-22@sha256:c0c3caa8e2a9ebee70c87fe45cd0bb431e996895ad9aa95557ac0ca9b21a06fb 0.7s done |   |   |  
Jun 21 2023 17:35:56 -0700 | #9 DONE 2.6s |   |   |  
Jun 21 2023 17:35:56 -0700 | Solve complete

After updating CRD with EnableServiceAccountTokenInjection field defaulting to false

Without client updates

I triggered another build without updating any code to verify that the new field is optional and defaults to false at https://mldemo4507.train-sandbox.domino.tech/environments/64920eb0bb2e9b737895a5b6/revisions/6493a50ebb2e9b737895a5f8/build/6493a50ebb2e9b737895a5fa/logs

The build completed successfully and did not inject the token as a build-arg

Jun 21 2023 18:34:07 -0700 | Validating registry credentials |   |   |  
-- | -- | -- | -- | --
Jun 21 2023 18:34:08 -0700 | Leasing buildkit worker |   |   |  
Jun 21 2023 18:37:49 -0700 | Confirming buildkitd connectivity |   |   |  
Jun 21 2023 18:37:49 -0700 | Buildkitd connectivity established |   |   |  
Jun 21 2023 18:37:49 -0700 | Fetching remote context |   |   |  
Jun 21 2023 18:37:49 -0700 | #1 [internal] load .dockerignore |   |   |  
Jun 21 2023 18:37:49 -0700 | #1 transferring context: 2B done |   |   |  
Jun 21 2023 18:37:49 -0700 | #1 DONE 0.0s |   |   |  
Jun 21 2023 18:37:49 -0700 |   |   |   |  
Jun 21 2023 18:37:49 -0700 | #2 [internal] load build definition from Dockerfile |   |   |  
Jun 21 2023 18:37:49 -0700 | #2 transferring dockerfile: 199B done |   |   |  
Jun 21 2023 18:37:49 -0700 | #2 DONE 0.0s |   |   |  
Jun 21 2023 18:37:49 -0700 |   |   |   |  
Jun 21 2023 18:37:49 -0700 | #3 [internal] load metadata for docker.io/library/alpine:latest |   |   |  
Jun 21 2023 18:37:51 -0700 | #3 DONE 1.8s |   |   |  
Jun 21 2023 18:37:51 -0700 |   |   |   |  
Jun 21 2023 18:37:51 -0700 | #4 [internal] load build context |   |   |  
Jun 21 2023 18:37:51 -0700 | #4 transferring context: 201B done |   |   |  
Jun 21 2023 18:37:51 -0700 | #4 DONE 0.0s |   |   |  
Jun 21 2023 18:37:51 -0700 |   |   |   |  
Jun 21 2023 18:37:51 -0700 | #5 [1/4] FROM docker.io/library/alpine:latest@sha256:82d1e9d7ed48a7523bdebc18cf6290bdb97b82302a8a9c27d4fe885949ea94d1 |   |   |  
Jun 21 2023 18:37:51 -0700 | #5 resolve docker.io/library/alpine:latest@sha256:82d1e9d7ed48a7523bdebc18cf6290bdb97b82302a8a9c27d4fe885949ea94d1 0.0s done |   |   |  
Jun 21 2023 18:37:51 -0700 | #5 CACHED |   |   |  
Jun 21 2023 18:37:51 -0700 |   |   |   |  
Jun 21 2023 18:37:51 -0700 | #6 [2/4] RUN echo "Injected ARG SERVICE_TOKEN: ${SERVICE_TOKEN}" |   |   |  
Jun 21 2023 18:37:51 -0700 | #0 0.083 Injected ARG SERVICE_TOKEN: |   |   |  
Jun 21 2023 18:37:51 -0700 |   |   |   |  
Jun 21 2023 18:37:51 -0700 | #6 DONE 0.1s |   |   |  
Jun 21 2023 18:37:51 -0700 |   |   |   |  
Jun 21 2023 18:37:51 -0700 | #7 [3/4] RUN echo "Main Dockerfile finished" |   |   |  
Jun 21 2023 18:37:51 -0700 | #0 0.067 Main Dockerfile finished |   |   |  
Jun 21 2023 18:37:51 -0700 |   |   |   |  
Jun 21 2023 18:37:51 -0700 | #7 DONE 0.1s |   |   |  
Jun 21 2023 18:37:51 -0700 |   |   |   |  
Jun 21 2023 18:37:51 -0700 | #8 [4/4] ADD files / |   |   |  
Jun 21 2023 18:37:51 -0700 | #8 DONE 0.0s |   |   |  
Jun 21 2023 18:37:51 -0700 |   |   |   |  
Jun 21 2023 18:37:51 -0700 | #9 exporting to image |   |   |  
Jun 21 2023 18:37:51 -0700 | #9 exporting layers |   |   |  
Jun 21 2023 18:37:51 -0700 | #9 exporting layers 0.1s done |   |   |  
Jun 21 2023 18:37:51 -0700 | #9 exporting manifest sha256:7a1a7e1591a36f9c11bef58cc5ea381c2b3b041cf64ca24cb37df76bae7d5729 done |   |   |  
Jun 21 2023 18:37:51 -0700 | #9 exporting config sha256:af12452cd2fd89fdf49e1ddb53eec8fa347aac83d5b68efd1ffffaaa25c3860a done |   |   |  
Jun 21 2023 18:37:51 -0700 | #9 pushing layers |   |   |  
Jun 21 2023 18:37:53 -0700 | #9 pushing layers 1.9s done |   |   |  
Jun 21 2023 18:37:53 -0700 | #9 pushing manifest for 172.20.88.105:5000/dominodatalab/environment:64920eb0bb2e9b737895a5b6-23@sha256:7a1a7e1591a36f9c11bef58cc5ea381c2b3b041cf64ca24cb37df76bae7d5729 |   |   |  
Jun 21 2023 18:37:53 -0700 | Solve complete |   |   |  
Jun 21 2023 18:37:53 -0700 | #9 pushing manifest for 172.20.88.105:5000/dominodatalab/environment:64920eb0bb2e9b737895a5b6-23@sha256:7a1a7e1591a36f9c11bef58cc5ea381c2b3b041cf64ca24cb37df76bae7d5729 0.7s done |   |   |  
Jun 21 2023 18:37:53 -0700 | #9 DONE 2.7s

Submitting a CR that sets the value EnableServiceAccountTokenInjection

** TBD **

@ddl-ebrown ddl-ebrown force-pushed the DOM-47678-build-service-credentials branch 2 times, most recently from 8ba7ab6 to 10a4895 Compare June 13, 2023 20:57
// cfg.Scopes...
jwt, err := kc.LoginClient(buildCtx, c.keycloakCfg.ClientID, c.keycloakCfg.ClientSecret, c.keycloakCfg.Realm)
if err != nil {
log.Error(err, fmt.Sprintf("Failed to acquire Keycloak credentials %s", c.keycloakCfg.ClientID))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this should fail the build?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the build requested it and it's not available, that would makes sense to me... just want to understand what the retry process looks like. I assume client is fully responsible for owning that process.

@ddl-ebrown ddl-ebrown force-pushed the DOM-47678-build-service-credentials branch 11 times, most recently from a81653b to 344b48e Compare June 22, 2023 00:24
 - Exposes config in values.yaml for chart, then inject into the
   equivalent secret values for the operator
 - Temporary import to prevent removal
@ddl-ebrown ddl-ebrown force-pushed the DOM-47678-build-service-credentials branch from 344b48e to 245af02 Compare June 22, 2023 00:49
@ddl-ebrown ddl-ebrown force-pushed the DOM-47678-build-service-credentials branch from 3043408 to a704e39 Compare June 22, 2023 01:50
 - When configured to inject service account tokens into the build, pass
   a build arg to the Docker build as SERVICE_TOKEN=<JWT>.

   This allows builds to contact additional services in the cluster
   using a specific service account identity.

   The value is consumed by adding to the Dockerfile:

   ARG SERVICE_TOKEN
 - If Keycloak configuration is disabled, but the incoming CR request
   asked for Keycloak token injection, then error / exit the build
@ddl-ebrown ddl-ebrown force-pushed the DOM-47678-build-service-credentials branch from a704e39 to 76f3d90 Compare June 22, 2023 02:03
@@ -409,6 +409,19 @@ func (suite *GenericImageBuilderTestSuite) TestImageBuilding() {
assert.Equalf(t, ib.Status.Phase, hephv1.PhaseSucceeded, "failed build with message %q", ib.Status.Conditions[0].Message)
})

suite.T().Run("token_injection", func(t *testing.T) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note - this test doesn't run as part of PRs :(

return ctrl.Result{}, c.phase.SetFailed(ctx, obj, fmt.Errorf("keycloak token acquire failed: %w", err))
}

obj.Spec.BuildArgs = append(obj.Spec.BuildArgs, fmt.Sprintf("%s=%s", hephv1.ServiceTokenArgName, jwt.AccessToken))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exposing as a build arg is a bad way to do this as sensitive values may find their way into logs or image metadata

@ddl-ebrown
Copy link
Contributor Author

Going to close this as we've decided to move forward with the approach in #106 instead

@ddl-ebrown ddl-ebrown closed this Jun 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants