Skip to content

Commit c552e05

Browse files
committed
Add an audience field to the config
1 parent 2eecf8e commit c552e05

File tree

6 files changed

+42
-22
lines changed

6 files changed

+42
-22
lines changed

api/v1alpha1/issuer_types.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,14 @@ type IssuerSpec struct {
8181
// effect on OAuth 2.0 Client Credential configuration - please specify the scopes for this method in an Opaque secret.
8282
// +optional
8383
Scopes string `json:"scopes,omitempty"`
84+
85+
// The audience value used when requesting a Bearer token from an ambient token provider implied
86+
// by the environment, rather than by commandSecretName. For example, could be set to
87+
// https://example.com when requesting an access token from Google's identity token provider. Ideally, this should be
88+
// the URL of your Command environment.Has no effect on OAuth 2.0 Client Credential configuration - please specify
89+
// the audience for this method in an Opaque secret.
90+
// +optional
91+
Audience string `json:"audience,omitempty"`
8492
}
8593

8694
func (i *Issuer) GetStatus() *IssuerStatus {

config/crd/bases/command-issuer.keyfactor.com_clusterissuers.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,13 @@ spec:
8585
api://{tenant ID}/.default when requesting an access token for Entra ID (DefaultAzureCredential). Has no
8686
effect on OAuth 2.0 Client Credential configuration - please specify the scopes for this method in an Opaque secret.
8787
type: string
88+
audience:
89+
description: |-
90+
The audience value used when requesting a Bearer token from an ambient token provider implied
91+
by the environment, rather than by commandSecretName. For example, could be set to
92+
https://example.com when requesting an access token from Google's identity token provider. Ideally, this should be
93+
the URL of your Command environment. Has no effect on OAuth 2.0 Client Credential configuration - please specify the audience for this method in an Opaque secret.
94+
type: string
8895
type: object
8996
status:
9097
description: IssuerStatus defines the observed state of Issuer

internal/command/client.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ var (
131131
type gcp struct {
132132
tokenSource oauth2.TokenSource
133133
scopes []string
134+
audience string
134135
}
135136

136137
// GetAccessToken implements TokenCredential.
@@ -146,7 +147,7 @@ func (g *gcp) GetAccessToken(ctx context.Context) (string, error) {
146147
log.Info(fmt.Sprintf("Generating a Google OIDC ID Token"))
147148

148149
// Use credentials to generate a JWT (requires a service account)
149-
tokenSource, err := idtoken.NewTokenSource(ctx, "command", idtoken.WithCredentialsJSON(credentials.JSON))
150+
tokenSource, err := idtoken.NewTokenSource(ctx, g.audience, idtoken.WithCredentialsJSON(credentials.JSON))
150151
if err != nil {
151152
return "", fmt.Errorf("%w: failed to get GCP ID Token Source: %w", errTokenFetchFailure, err)
152153
}
@@ -178,9 +179,10 @@ func (g *gcp) GetAccessToken(ctx context.Context) (string, error) {
178179
return token.AccessToken, nil
179180
}
180181

181-
func newGCPDefaultCredentialSource(ctx context.Context, scopes []string) (*gcp, error) {
182+
func newGCPDefaultCredentialSource(ctx context.Context, audience string, scopes []string) (*gcp, error) {
182183
source := &gcp{
183-
scopes: scopes,
184+
scopes: scopes,
185+
audience: audience,
184186
}
185187
_, err := source.GetAccessToken(ctx)
186188
if err != nil {
@@ -191,8 +193,8 @@ func newGCPDefaultCredentialSource(ctx context.Context, scopes []string) (*gcp,
191193
}
192194

193195
// TODO: Remove this before merging
194-
func NewGCPDefaultCredentialSource(ctx context.Context, scopes []string) (*gcp, error) {
195-
return newGCPDefaultCredentialSource(ctx, scopes)
196+
func NewGCPDefaultCredentialSource(ctx context.Context, audience string, scopes []string) (*gcp, error) {
197+
return newGCPDefaultCredentialSource(ctx, audience, scopes)
196198
}
197199

198200
// TODO: Remove this before merging

internal/command/command.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,13 @@ type signer struct {
7575
}
7676

7777
type Config struct {
78-
Hostname string
79-
APIPath string
80-
CaCertsBytes []byte
81-
BasicAuth *BasicAuth
82-
OAuth *OAuth
83-
AmbientCredentialScopes []string
78+
Hostname string
79+
APIPath string
80+
CaCertsBytes []byte
81+
BasicAuth *BasicAuth
82+
OAuth *OAuth
83+
AmbientCredentialScopes []string
84+
AmbientCredentialAudience string
8485
}
8586

8687
func (c *Config) validate() error {
@@ -207,7 +208,7 @@ func newServerConfig(ctx context.Context, config *Config) (*auth_providers.Serve
207208
log.Info("couldn't obtain Azure DefaultAzureCredential. trying GCP ApplicationDefaultCredentials", "error", err)
208209

209210
var innerErr error
210-
source, innerErr = newGCPDefaultCredentialSource(ctx, config.AmbientCredentialScopes)
211+
source, innerErr = newGCPDefaultCredentialSource(ctx, config.AmbientCredentialAudience, config.AmbientCredentialScopes)
211212
if innerErr != nil {
212213
return nil, fmt.Errorf("%w: azure err: %w. gcp err: %w", errAmbientCredentialCreationFailure, err, innerErr)
213214
}

internal/controller/issuer_controller.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -235,12 +235,13 @@ func commandConfigFromIssuer(ctx context.Context, c client.Client, issuer comman
235235
}
236236

237237
return &command.Config{
238-
Hostname: issuer.GetSpec().Hostname,
239-
APIPath: issuer.GetSpec().APIPath,
240-
CaCertsBytes: caCertBytes,
241-
BasicAuth: basicAuth,
242-
OAuth: oauth,
243-
AmbientCredentialScopes: strings.Split(issuer.GetSpec().Scopes, ","),
238+
Hostname: issuer.GetSpec().Hostname,
239+
APIPath: issuer.GetSpec().APIPath,
240+
CaCertsBytes: caCertBytes,
241+
BasicAuth: basicAuth,
242+
OAuth: oauth,
243+
AmbientCredentialScopes: strings.Split(issuer.GetSpec().Scopes, ","),
244+
AmbientCredentialAudience: issuer.GetSpec().Audience,
244245
}, nil
245246
}
246247

sample/main.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func main() {
3333
}, funcr.Options{})
3434
ctx := logr.NewContext(context.Background(), logger)
3535
log := log.FromContext(ctx)
36-
source, err := command.NewGCPDefaultCredentialSource(ctx, []string{"openid", "profile", "email", "https://www.googleapis.com/auth/cloud-platform"})
36+
source, err := command.NewGCPDefaultCredentialSource(ctx, "https://example.com", []string{"openid", "profile", "email", "https://www.googleapis.com/auth/cloud-platform"})
3737
if err != nil {
3838
log.Error(err, fmt.Sprintf("Error getting credentials: %s", err))
3939
return
@@ -44,9 +44,10 @@ func main() {
4444
return
4545
}
4646
log.Info(fmt.Sprintf("source obtained: %s", token))
47-
isValid := command.ValidateToken(ctx, token, "command")
47+
isValid := command.ValidateToken(ctx, token, "https://example1.com")
4848
if !isValid {
49-
log.Info(fmt.Sprintf("Token not valid"))
49+
log.Info(fmt.Sprintf("ERROR: Token not valid"))
50+
} else {
51+
log.Info(fmt.Sprintf("Success! Token successfully validated"))
5052
}
51-
log.Info(fmt.Sprintf("Token successfully validated"))
5253
}

0 commit comments

Comments
 (0)