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

ci-10525- initial oidc support #89

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ name: default
pool:
use: ubuntu


platform:
os: linux
arch: amd64
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ docker build \
--label org.label-schema.build-date=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
--label org.label-schema.vcs-ref=$(git rev-parse --short HEAD) \
--file docker/ecr/Dockerfile.linux.amd64 --tag plugins/kaniko-ecr .

docker build \
--label org.label-schema.build-date=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
--label org.label-schema.vcs-ref=$(git rev-parse --short HEAD) \
--file docker/gar/Dockerfile.linux.amd64 --tag plugins/kaniko-gar .
```

## Usage
Expand Down
83 changes: 81 additions & 2 deletions cmd/kaniko-gar/main.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package main

import (
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"os"

"github.com/drone/drone-kaniko/internal"

"github.com/joho/godotenv"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
Expand Down Expand Up @@ -164,6 +168,31 @@ func main() {
Usage: "build only used stages",
EnvVar: "PLUGIN_SKIP_UNUSED_STAGES",
},
cli.StringFlag{
Name: "oidc-token",
Usage: "OIDC token to use for authentication",
EnvVar: "PLUGIN_OIDC_TOKEN_ID",
},
cli.StringFlag{
Name: "project-number",
Usage: "Google project number",
EnvVar: "PLUGIN_PROJECT_NUMBER",
},
cli.StringFlag{
Name: "pool-id",
Usage: "Google pool id",
EnvVar: "PLUGIN_POOL_ID",
},
cli.StringFlag{
Name: "provider-id",
Usage: "Google provider id",
EnvVar: "PLUGIN_PROVIDER_ID",
},
cli.StringFlag{
Name: "service-account-email",
Usage: "Google service account email",
EnvVar: "PLUGIN_SERVICE_ACCOUNT_EMAIL",
},
}

if err := app.Run(os.Args); err != nil {
Expand All @@ -174,14 +203,26 @@ func main() {
func run(c *cli.Context) error {
noPush := c.Bool("no-push")
jsonKey := c.String("json-key")

idToken := c.String("oidc-token")
projectNumber := c.String("project-number")
poolId := c.String("pool-id")
providerId := c.String("provider-id")
serviceAccountEmail := c.String("service-account-email")
registry := c.String("registry")
// JSON key may not be set in the following cases:
// 1. Image does not need to be pushed to GAR.
// 2. Workload identity is set on GKE in which pod will inherit the credentials via service account.
if jsonKey != "" {
if err := setupGARAuth(jsonKey); err != nil {
return err
}
} else if idToken != "" {
accessToken := setupOIDCAuth(idToken, projectNumber, poolId, providerId, serviceAccountEmail)
if accessToken != "" {
if err := setupAccessTokenAuth(accessToken, registry); err != nil {
return err
}
}
}

plugin := kaniko.Plugin{
Expand Down Expand Up @@ -212,7 +253,7 @@ func run(c *cli.Context) error {
Artifact: kaniko.Artifact{
Tags: c.StringSlice("tags"),
Repo: c.String("repo"),
Registry: c.String("registry"),
Registry: registry,
ArtifactFile: c.String("artifact-file"),
RegistryType: artifact.GAR,
},
Expand All @@ -232,3 +273,41 @@ func setupGARAuth(jsonKey string) error {
}
return nil
}

func setupAccessTokenAuth(accessToken, registryURL string) error {
dockerConfig := map[string]interface{}{
"auths": map[string]interface{}{
registryURL: map[string]string{
"auth": encodeAccessToken(accessToken),
},
},
}

dockerConfigJson, err := json.Marshal(dockerConfig)
if err != nil {
return fmt.Errorf("failed to marshal docker config: %w", err)
}

if err := ioutil.WriteFile("/root/.docker/config.json", dockerConfigJson, 0600); err != nil {
return fmt.Errorf("failed to write docker config file: %w", err)
}

return nil
}

func encodeAccessToken(token string) string {
auth := base64.StdEncoding.EncodeToString([]byte("_json_key:" + token))
return auth
}

func setupOIDCAuth(idToken, projectId, poolId, providerId, serviceAccountEmail string) string {
federalToken, err := internal.GetFederalToken(idToken, projectId, poolId, providerId)
if err != nil {
logrus.Fatalf("Error (getFederalToken): %s", err)
}
accessToken, err := internal.GetGoogleCloudAccessToken(federalToken, serviceAccountEmail)
if err != nil {
logrus.Fatalf("Error (getGoogleCloudAccessToken): %s", err)
}
return accessToken
}
28 changes: 21 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,18 @@ require (
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.13.8
github.com/aws/smithy-go v1.12.0
github.com/coreos/go-semver v0.3.0
github.com/google/go-cmp v0.5.8
github.com/google/go-cmp v0.6.0
github.com/hashicorp/go-version v1.6.0
github.com/joho/godotenv v1.4.0
github.com/pkg/errors v0.9.1
github.com/sirupsen/logrus v1.8.1
github.com/urfave/cli v1.22.9
golang.org/x/mod v0.5.1
golang.org/x/mod v0.8.0
)

require (
cloud.google.com/go/compute v1.23.1 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v0.5.3 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.12.9 // indirect
Expand All @@ -32,15 +34,27 @@ require (
github.com/aws/aws-sdk-go-v2/service/sts v1.16.9 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/s2a-go v0.1.7 // indirect
github.com/google/uuid v1.4.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect
golang.org/x/net v0.0.0-20220725212005-46097bf591d3 // indirect
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
golang.org/x/text v0.3.7 // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/oauth2 v0.13.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
google.golang.org/api v0.151.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231030173426-d783a09b4405 // indirect
google.golang.org/grpc v1.59.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
)

go 1.21
Loading