Skip to content

Commit

Permalink
support client credentials being loaded from file (#48)
Browse files Browse the repository at this point in the history
The client creds secret, previously had to be specified in the config.
When deploying this with the helm chart, this would require the value
to be stored in plain text in the config map.

To solve this, we now accept a file path for both clientID and clientSecret.

If either attributes value is prefixed with `file://` the defined file is attempted to be loaded.
If no file is found, or the file fails to be read, an error is returned.

Currently the file is only read once at startup.
However a future improvement could provide support for allowing hot reloading of the file.

Signed-off-by: Mike Mason <[email protected]>
  • Loading branch information
mikemrm authored May 7, 2024
1 parent c45d6b4 commit 45ba684
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 4 deletions.
4 changes: 2 additions & 2 deletions chart/iam-runtime-infratographer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ iam-runtime-infratographer:
| config.accessToken.exchange.grantType | string | urn:ietf:params:oauth:grant-type:token-exchange | grantType configures the grant type |
| config.accessToken.exchange.issuer | string | `""` | issuer specifies the URL for the issuer for the exchanged token. The Issuer must support OpenID discovery to discover the token endpoint. |
| config.accessToken.exchange.tokenType | string | urn:ietf:params:oauth:token-type:jwt | tokenType configures the token type |
| config.accessToken.source.clientCredentials.clientID | string | `""` | clientID is the client credentials id which is used to retrieve a token from the issuer. |
| config.accessToken.source.clientCredentials.clientSecret | string | `""` | clientSecret is the client credentials secret which is used to retrieve a token from the issuer. |
| config.accessToken.source.clientCredentials.clientID | string | `""` | clientID is the client credentials id which is used to retrieve a token from the issuer. This attribute also supports a file path by prefixing the value with `file://`. example: `file:///var/secrets/client-id` |
| config.accessToken.source.clientCredentials.clientSecret | string | `""` | clientSecret is the client credentials secret which is used to retrieve a token from the issuer. This attribute also supports a file path by prefixing the value with `file://`. example: `file:///var/secrets/client-secret` |
| config.accessToken.source.clientCredentials.issuer | string | `""` | issuer specifies the URL for the issuer for the token request. The Issuer must support OpenID discovery to discover the token endpoint. |
| config.accessToken.source.fileToken.noReuseToken | bool | `false` | noReuseToken if enabled disables reuse of tokens while they're still valid. |
| config.accessToken.source.fileToken.tokenPath | string | `""` | tokenPath is the path to the source jwt token. |
Expand Down
4 changes: 4 additions & 0 deletions chart/iam-runtime-infratographer/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,12 @@ config:
# The Issuer must support OpenID discovery to discover the token endpoint.
issuer: ""
# -- clientID is the client credentials id which is used to retrieve a token from the issuer.
# This attribute also supports a file path by prefixing the value with `file://`.
# example: `file:///var/secrets/client-id`
clientID: ""
# -- clientSecret is the client credentials secret which is used to retrieve a token from the issuer.
# This attribute also supports a file path by prefixing the value with `file://`.
# example: `file:///var/secrets/client-secret`
clientSecret: ""
exchange:
# -- issuer specifies the URL for the issuer for the exchanged token.
Expand Down
33 changes: 31 additions & 2 deletions internal/accesstoken/tokensource.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ package accesstoken
import (
"context"
"fmt"
"net/url"
"os"
"path/filepath"
"strings"

"go.infratographer.com/iam-runtime-infratographer/internal/jwt"
"golang.org/x/oauth2"
Expand Down Expand Up @@ -57,9 +61,34 @@ func (c ClientCredentialConfig) toTokenSource(ctx context.Context) (oauth2.Token
return nil, fmt.Errorf("failed to fetch issuer token endpoint: %w", err)
}

clientID := c.ClientID
clientSecret := c.ClientSecret

if uri, err := url.ParseRequestURI(clientID); err == nil && uri.Scheme == "file" {
file := filepath.Join(uri.Host, uri.Path)

content, err := os.ReadFile(file)
if err != nil {
return nil, fmt.Errorf("failed to read file %s: %w", file, err)
}

clientID = strings.TrimSpace(string(content))
}

if uri, err := url.ParseRequestURI(clientSecret); err == nil && uri.Scheme == "file" {
file := filepath.Join(uri.Host, uri.Path)

content, err := os.ReadFile(file)
if err != nil {
return nil, fmt.Errorf("failed to read file %s: %w", file, err)
}

clientSecret = strings.TrimSpace(string(content))
}

config := clientcredentials.Config{
ClientID: c.ClientID,
ClientSecret: c.ClientSecret,
ClientID: clientID,
ClientSecret: clientSecret,
TokenURL: tokenEndpoint,
}

Expand Down

0 comments on commit 45ba684

Please sign in to comment.