Skip to content

Commit

Permalink
Adds support for setting customg it auth
Browse files Browse the repository at this point in the history
By default git auth supports some default secret values for fetching
auth credentials (`GIT_AUTH_TOKEN` and `GIT_AUTH_HEADER`).
This change allows customizing that to different secret names.

Signed-off-by: Brian Goff <[email protected]>
  • Loading branch information
cpuguy83 committed Oct 3, 2024
1 parent 96aeb52 commit 4ec9a70
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 5 deletions.
21 changes: 21 additions & 0 deletions docs/spec.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,24 @@
"type": "object",
"description": "GeneratorGomod is used to generate a go module cache from go module sources"
},
"GitAuth": {
"properties": {
"header": {
"type": "string",
"description": "Header is the name of the secret which contains the git auth header.\nwhen using git auth header based authentication.\nNote: This should not have the *actual* secret value, just the name of\nthe secret which was specified as a build secret."
},
"token": {
"type": "string",
"description": "Token is the name of the secret which contains a git auth token when using\ntoken based authentication.\nNote: This should not have the *actual* secret value, just the name of\nthe secret which was specified as a build secret."
},
"ssh": {
"type": "string",
"description": "SSH is the name of the secret which contains the ssh auth into when using\nssh based auth.\nNote: This should not have the *actual* secret value, just the name of\nthe secret which was specified as a build secret."
}
},
"additionalProperties": false,
"type": "object"
},
"ImageConfig": {
"properties": {
"entrypoint": {
Expand Down Expand Up @@ -716,6 +734,9 @@
},
"keepGitDir": {
"type": "boolean"
},
"auth": {
"$ref": "#/$defs/GitAuth"
}
},
"additionalProperties": false,
Expand Down
6 changes: 6 additions & 0 deletions helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -413,3 +413,9 @@ func (s *Spec) GetPackageDeps(target string) *PackageDependencies {
}
return s.Dependencies
}

type gitOptionFunc func(*llb.GitInfo)

func (f gitOptionFunc) SetGitOption(gi *llb.GitInfo) {
f(gi)
}
1 change: 1 addition & 0 deletions source.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ func (src *SourceGit) AsState(opts ...llb.ConstraintsOpt) (llb.State, error) {
gOpts = append(gOpts, llb.KeepGitDir())
}
gOpts = append(gOpts, withConstraints(opts))
gOpts = append(gOpts, src.Auth.LLBOpt())

st := llb.Git(ref.Remote, src.Commit, gOpts...)
return st, nil
Expand Down
56 changes: 56 additions & 0 deletions source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,19 @@ func TestSourceGitSSH(t *testing.T) {

checkFilter(t, ops2[1].GetFile(), &src)
})

t.Run("auth", func(t *testing.T) {
src := Source{
Git: &SourceGit{
URL: fmt.Sprintf("user@%s:test.git", addr),
Commit: t.Name(),
},
}

ops := getSourceOp(ctx, t, src)
checkGitOp(t, ops, &src)
})

}

func TestSourceGitHTTP(t *testing.T) {
Expand Down Expand Up @@ -148,6 +161,22 @@ func TestSourceGitHTTP(t *testing.T) {

checkFilter(t, ops2[1].GetFile(), &src)
})

t.Run("auth", func(t *testing.T) {
src := Source{
Git: &SourceGit{
URL: "https://localhost/test.git",
Commit: t.Name(),
Auth: GitAuth{
Header: "some header",
Token: "some token",
},
},
}

ops := getSourceOp(ctx, t, src)
checkGitOp(t, ops, &src)
})
}

func TestSourceHTTP(t *testing.T) {
Expand Down Expand Up @@ -876,6 +905,33 @@ func checkGitOp(t *testing.T, ops []*pb.Op, src *Source) {
if op.Attrs["git.fullurl"] != src.Git.URL {
t.Errorf("expected git.fullurl %q, got %q", src.Git.URL, op.Attrs["git.fullurl"])
}

const (
defaultAuthHeader = "GIT_AUTH_HEADER"
defaultAuthToken = "GIT_AUTH_TOKEN"
defaultAuthSSH = "default"
)

hdr := defaultAuthHeader
if src.Git.Auth.Header != "" {
hdr = src.Git.Auth.Header
}
assert.Check(t, cmp.Equal(op.Attrs["git.authheadersecret"], hdr), op.Attrs)

token := defaultAuthToken
if src.Git.Auth.Token != "" {
token = src.Git.Auth.Token
}
assert.Check(t, cmp.Equal(op.Attrs["git.authtokensecret"], token), op.Attrs)

if !strings.HasPrefix(src.Git.URL, "http") {
// ssh settings are only set when using ssh based auth
ssh := defaultAuthSSH
if src.Git.Auth.SSH != "" {
ssh = src.Git.Auth.SSH
}
assert.Check(t, cmp.Equal(op.Attrs["git.mountsshsock"], ssh), op)
}
}

func checkFilter(t *testing.T, op *pb.FileOp, src *Source) {
Expand Down
48 changes: 45 additions & 3 deletions spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strings"
"time"

"github.com/moby/buildkit/client/llb"
"github.com/opencontainers/go-digest"
)

Expand Down Expand Up @@ -141,9 +142,50 @@ type SourceDockerImage struct {
}

type SourceGit struct {
URL string `yaml:"url" json:"url"`
Commit string `yaml:"commit" json:"commit"`
KeepGitDir bool `yaml:"keepGitDir" json:"keepGitDir"`
URL string `yaml:"url" json:"url"`
Commit string `yaml:"commit" json:"commit"`
KeepGitDir bool `yaml:"keepGitDir" json:"keepGitDir"`
Auth GitAuth `yaml:"auth,omitempty" json:"auth,omitempty"`
}

type GitAuth struct {
// Header is the name of the secret which contains the git auth header.
// when using git auth header based authentication.
// Note: This should not have the *actual* secret value, just the name of
// the secret which was specified as a build secret.
Header string `yaml:"header,omitempty" json:"header,omitempty"`
// Token is the name of the secret which contains a git auth token when using
// token based authentication.
// Note: This should not have the *actual* secret value, just the name of
// the secret which was specified as a build secret.
Token string `yaml:"token,omitempty" json:"token,omitempty"`
// SSH is the name of the secret which contains the ssh auth into when using
// ssh based auth.
// Note: This should not have the *actual* secret value, just the name of
// the secret which was specified as a build secret.
SSH string `yaml:"ssh,omitempty" json:"ssh,omitempty"`
}

// LLBOpt returns an [llb.GitOption] which sets the auth header and token secret
// values in LLB if they are set.
func (a *GitAuth) LLBOpt() llb.GitOption {
return gitOptionFunc(func(gi *llb.GitInfo) {
if a == nil {
return
}

if a.Header != "" {
gi.AuthHeaderSecret = a.Header
}

if a.Token != "" {
gi.AuthTokenSecret = a.Token
}

if a.SSH != "" {
gi.MountSSHSock = a.SSH
}
})
}

// SourceHTTP is used to download a file from an HTTP(s) URL.
Expand Down
23 changes: 21 additions & 2 deletions website/docs/sources.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,31 @@ You can override this behavior by setting `keepGitDir: true` in the git configur

Git repositories are considered to be "directory" sources.

Authentication will be handled using some defaults:
Authentication will be handled using some default secret names which are fetched
from the client:

1. Local SSH agent
1. Default SSH agent
2. Providing a build secret called `GIT_AUTH_HEADER` for header based auth
3. Providing a build secret called `GIT_AUTH_TOKEN` for token based auth

You can customize each of these by setting the appropriate field in the
git auth section (shown below with default values):

```yaml
someSource1:
git:
# This uses an SSH style git URL.
url: [email protected]:myOrg/myRepo.git
commit: 1234567890abcdef
auth:
header: GIT_AUTH_HEADER # Default header secret used
token: GIT_AUTH_TOKEN # Default token secret used
ssh: default # Default SSH secret used
```

Note: These are secret names which are used to reference the secrets provided
by the client, not the actual secret values.

### HTTP

HTTP sources fetch a file from an HTTP URL.
Expand Down

0 comments on commit 4ec9a70

Please sign in to comment.