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

Add env variable support for configuration #339

Open
wants to merge 11 commits 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 .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*.swp
chart/docker-auth/Chart.lock
auth_server/auth_server.exe
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ A helm chart is available in the folder [chart/docker-auth](chart/docker-auth).

A public Docker image is available on Docker Hub: [cesanta/docker_auth](https://hub.docker.com/r/cesanta/docker_auth/).

----------

Tags available:
- `:edge` - bleeding edge, usually works but breaking config changes are possible. You probably do not want to use this in production.
- `:latest` - latest tagged release, will line up with `:1` tag
Expand All @@ -45,6 +47,19 @@ Tags available:
The binary takes a single argument - path to the config file.
If no arguments are given, the Dockerfile defaults to `/config/auth_config.yml`.

----------

You may also overwrite any configs in the file using `ENV` variables. This is useful to inject secrets or other sensitive data from external stores into your configs without having to manage building a whole file.
Follow these guidelines:

- All variables must start with `AUTH__`
- A double underscore `__` is used to delineate between levels. This is to account for variables with a single underscore in their name. e.g. `AUTH__SERVER__LETSENCRYPT__CACHE_DIR=/some/dir`

see the [config_test.go](auth_server/server/config_test.go) for sample usage

----------


Example command line:

```{r, engine='bash', count_lines}
Expand All @@ -57,6 +72,8 @@ $ docker run \

See the [example config files](https://github.com/cesanta/docker_auth/tree/main/examples/) to get an idea of what is possible.

----------

## Troubleshooting

Run with increased verbosity:
Expand Down
4 changes: 2 additions & 2 deletions auth_server/authn/ext_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ import (
)

type ExtAuthConfig struct {
Command string `yaml:"command"`
Args []string `yaml:"args"`
Command string `mapstructure:"command"`
Args []string `mapstructure:"args"`
}

type ExtAuthStatus int
Expand Down
32 changes: 16 additions & 16 deletions auth_server/authn/github_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,28 +57,28 @@ type ParentGitHubTeam struct {
}

type GitHubAuthConfig struct {
Organization string `yaml:"organization,omitempty"`
ClientId string `yaml:"client_id,omitempty"`
ClientSecret string `yaml:"client_secret,omitempty"`
ClientSecretFile string `yaml:"client_secret_file,omitempty"`
TokenDB string `yaml:"token_db,omitempty"`
GCSTokenDB *GitHubGCSStoreConfig `yaml:"gcs_token_db,omitempty"`
RedisTokenDB *GitHubRedisStoreConfig `yaml:"redis_token_db,omitempty"`
HTTPTimeout time.Duration `yaml:"http_timeout,omitempty"`
RevalidateAfter time.Duration `yaml:"revalidate_after,omitempty"`
GithubWebUri string `yaml:"github_web_uri,omitempty"`
GithubApiUri string `yaml:"github_api_uri,omitempty"`
RegistryUrl string `yaml:"registry_url,omitempty"`
Organization string `mapstructure:"organization,omitempty"`
ClientId string `mapstructure:"client_id,omitempty"`
ClientSecret string `mapstructure:"client_secret,omitempty"`
ClientSecretFile string `mapstructure:"client_secret_file,omitempty"`
TokenDB string `mapstructure:"token_db,omitempty"`
GCSTokenDB *GitHubGCSStoreConfig `mapstructure:"gcs_token_db,omitempty"`
RedisTokenDB *GitHubRedisStoreConfig `mapstructure:"redis_token_db,omitempty"`
HTTPTimeout time.Duration `mapstructure:"http_timeout,omitempty"`
RevalidateAfter time.Duration `mapstructure:"revalidate_after,omitempty"`
GithubWebUri string `mapstructure:"github_web_uri,omitempty"`
GithubApiUri string `mapstructure:"github_api_uri,omitempty"`
RegistryUrl string `mapstructure:"registry_url,omitempty"`
}

type GitHubGCSStoreConfig struct {
Bucket string `yaml:"bucket,omitempty"`
ClientSecretFile string `yaml:"client_secret_file,omitempty"`
Bucket string `mapstructure:"bucket,omitempty"`
ClientSecretFile string `mapstructure:"client_secret_file,omitempty"`
}

type GitHubRedisStoreConfig struct {
ClientOptions *redis.Options `yaml:"redis_options,omitempty"`
ClusterOptions *redis.ClusterOptions `yaml:"redis_cluster_options,omitempty"`
ClientOptions *redis.Options `mapstructure:"redis_options,omitempty"`
ClusterOptions *redis.ClusterOptions `mapstructure:"redis_cluster_options,omitempty"`
}

type GitHubAuthRequest struct {
Expand Down
41 changes: 19 additions & 22 deletions auth_server/authn/gitlab_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,20 @@ type ParentGitlabTeam struct {
}

type GitlabAuthConfig struct {
Organization string `yaml:"organization,omitempty"`
ClientId string `yaml:"client_id,omitempty"`
ClientSecret string `yaml:"client_secret,omitempty"`
ClientSecretFile string `yaml:"client_secret_file,omitempty"`
TokenDB string `yaml:"token_db,omitempty"`
GCSTokenDB *GitlabGCSStoreConfig `yaml:"gcs_token_db,omitempty"`
RedisTokenDB *GitlabRedisStoreConfig `yaml:"redis_token_db,omitempty"`
HTTPTimeout time.Duration `yaml:"http_timeout,omitempty"`
RevalidateAfter time.Duration `yaml:"revalidate_after,omitempty"`
GitlabWebUri string `yaml:"gitlab_web_uri,omitempty"`
GitlabApiUri string `yaml:"gitlab_api_uri,omitempty"`
RegistryUrl string `yaml:"registry_url,omitempty"`
GrantType string `yaml:"grant_type,omitempty"`
RedirectUri string `yaml:"redirect_uri,omitempty"`
Organization string `mapstructure:"organization,omitempty"`
ClientId string `mapstructure:"client_id,omitempty"`
ClientSecret string `mapstructure:"client_secret,omitempty"`
ClientSecretFile string `mapstructure:"client_secret_file,omitempty"`
TokenDB string `mapstructure:"token_db,omitempty"`
GCSTokenDB *GitlabGCSStoreConfig `mapstructure:"gcs_token_db,omitempty"`
RedisTokenDB *GitlabRedisStoreConfig `mapstructure:"redis_token_db,omitempty"`
HTTPTimeout time.Duration `mapstructure:"http_timeout,omitempty"`
RevalidateAfter time.Duration `mapstructure:"revalidate_after,omitempty"`
GitlabWebUri string `mapstructure:"gitlab_web_uri,omitempty"`
GitlabApiUri string `mapstructure:"gitlab_api_uri,omitempty"`
RegistryUrl string `mapstructure:"registry_url,omitempty"`
GrantType string `mapstructure:"grant_type,omitempty"`
RedirectUri string `mapstructure:"redirect_uri,omitempty"`
}

type CodeToGitlabTokenResponse struct {
Expand All @@ -86,13 +86,13 @@ type CodeToGitlabTokenResponse struct {
}

type GitlabGCSStoreConfig struct {
Bucket string `yaml:"bucket,omitempty"`
ClientSecretFile string `yaml:"client_secret_file,omitempty"`
Bucket string `mapstructure:"bucket,omitempty"`
ClientSecretFile string `mapstructure:"client_secret_file,omitempty"`
}

type GitlabRedisStoreConfig struct {
ClientOptions *redis.Options `yaml:"redis_options,omitempty"`
ClusterOptions *redis.ClusterOptions `yaml:"redis_cluster_options,omitempty"`
ClientOptions *redis.Options `mapstructure:"redis_options,omitempty"`
ClusterOptions *redis.ClusterOptions `mapstructure:"redis_cluster_options,omitempty"`
}

type GitlabAuthRequest struct {
Expand All @@ -114,7 +114,6 @@ type GitlabAuth struct {
tmplResult *template.Template
}


func NewGitlabAuth(c *GitlabAuthConfig) (*GitlabAuth, error) {
var db TokenDB
var err error
Expand Down Expand Up @@ -240,7 +239,6 @@ func (glab *GitlabAuth) doGitlabAuthCreateToken(rw http.ResponseWriter, code str

glog.Infof("New GitLab auth token for %s", user)


v := &TokenDBValue{
TokenType: c2t.TokenType,
AccessToken: c2t.AccessToken,
Expand All @@ -257,7 +255,7 @@ func (glab *GitlabAuth) doGitlabAuthCreateToken(rw http.ResponseWriter, code str

func (glab *GitlabAuth) validateGitlabAccessToken(token string) (user string, err error) {
glog.Infof("Gitlab API: Fetching user info")
req, err := http.NewRequest("GET", fmt.Sprintf("%s/user", glab.getGitlabApiUri()),nil)
req, err := http.NewRequest("GET", fmt.Sprintf("%s/user", glab.getGitlabApiUri()), nil)

if err != nil {
err = fmt.Errorf("could not create request to get information for token %s: %s", token, err)
Expand Down Expand Up @@ -312,7 +310,6 @@ func (glab *GitlabAuth) checkGitlabOrganization(token, user string) (err error)
return fmt.Errorf("Unknown status for membership of organization %s: %s", glab.config.Organization, resp.Status)
}


func (glab *GitlabAuth) validateGitlabServerToken(user string) (*TokenDBValue, error) {
v, err := glab.db.GetValue(user)
if err != nil || v == nil {
Expand Down
12 changes: 6 additions & 6 deletions auth_server/authn/google_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ import (
)

type GoogleAuthConfig struct {
Domain string `yaml:"domain,omitempty"`
ClientId string `yaml:"client_id,omitempty"`
ClientSecret string `yaml:"client_secret,omitempty"`
ClientSecretFile string `yaml:"client_secret_file,omitempty"`
TokenDB string `yaml:"token_db,omitempty"`
HTTPTimeout int `yaml:"http_timeout,omitempty"`
Domain string `mapstructure:"domain,omitempty"`
ClientId string `mapstructure:"client_id,omitempty"`
ClientSecret string `mapstructure:"client_secret,omitempty"`
ClientSecretFile string `mapstructure:"client_secret_file,omitempty"`
TokenDB string `mapstructure:"token_db,omitempty"`
HTTPTimeout int `mapstructure:"http_timeout,omitempty"`
}

type GoogleAuthRequest struct {
Expand Down
24 changes: 12 additions & 12 deletions auth_server/authn/ldap_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,21 @@ import (
)

type LabelMap struct {
Attribute string `yaml:"attribute,omitempty"`
ParseCN bool `yaml:"parse_cn,omitempty"`
Attribute string `mapstructure:"attribute,omitempty"`
ParseCN bool `mapstructure:"parse_cn,omitempty"`
}

type LDAPAuthConfig struct {
Addr string `yaml:"addr,omitempty"`
TLS string `yaml:"tls,omitempty"`
InsecureTLSSkipVerify bool `yaml:"insecure_tls_skip_verify,omitempty"`
CACertificate string `yaml:"ca_certificate,omitempty"`
Base string `yaml:"base,omitempty"`
Filter string `yaml:"filter,omitempty"`
BindDN string `yaml:"bind_dn,omitempty"`
BindPasswordFile string `yaml:"bind_password_file,omitempty"`
LabelMaps map[string]LabelMap `yaml:"labels,omitempty"`
InitialBindAsUser bool `yaml:"initial_bind_as_user,omitempty"`
Addr string `mapstructure:"addr,omitempty"`
TLS string `mapstructure:"tls,omitempty"`
InsecureTLSSkipVerify bool `mapstructure:"insecure_tls_skip_verify,omitempty"`
CACertificate string `mapstructure:"ca_certificate,omitempty"`
Base string `mapstructure:"base,omitempty"`
Filter string `mapstructure:"filter,omitempty"`
BindDN string `mapstructure:"bind_dn,omitempty"`
BindPasswordFile string `mapstructure:"bind_password_file,omitempty"`
LabelMaps map[string]LabelMap `mapstructure:"labels,omitempty"`
InitialBindAsUser bool `mapstructure:"initial_bind_as_user,omitempty"`
}

type LDAPAuth struct {
Expand Down
7 changes: 3 additions & 4 deletions auth_server/authn/mongo_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ import (
)

type MongoAuthConfig struct {
MongoConfig *mgo_session.Config `yaml:"dial_info,omitempty"`
Collection string `yaml:"collection,omitempty"`
MongoConfig *mgo_session.Config `mapstructure:"dial_info,omitempty"`
Collection string `mapstructure:"collection,omitempty"`
}

type MongoAuth struct {
Expand Down Expand Up @@ -102,8 +102,7 @@ func (mauth *MongoAuth) authenticate(account string, password api.PasswordString
var dbUserRecord authUserEntry
collection := mauth.session.Database(mauth.config.MongoConfig.DialInfo.Database).Collection(mauth.config.Collection)


filter := bson.D{{"username", account}}
filter := bson.D{{"username", account}}
err := collection.FindOne(context.TODO(), filter).Decode(&dbUserRecord)

// If we connect and get no results we return a NoMatch so auth can fall-through
Expand Down
19 changes: 10 additions & 9 deletions auth_server/authn/oidc_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@ import (
"encoding/json"
"errors"
"fmt"
"golang.org/x/oauth2"
"html/template"
"io/ioutil"
"net/http"
"strings"
"time"

"golang.org/x/oauth2"

"github.com/coreos/go-oidc/v3/oidc"

"github.com/cesanta/glog"
Expand All @@ -39,19 +40,19 @@ import (
type OIDCAuthConfig struct {
// --- necessary ---
// URL of the authentication provider. Must be able to serve the /.well-known/openid-configuration
Issuer string `yaml:"issuer,omitempty"`
Issuer string `mapstructure:"issuer,omitempty"`
// URL of the auth server. Has to end with /oidc_auth
RedirectURL string `yaml:"redirect_url,omitempty"`
RedirectURL string `mapstructure:"redirect_url,omitempty"`
// ID and secret, priovided by the OIDC provider after registration of the auth server
ClientId string `yaml:"client_id,omitempty"`
ClientSecret string `yaml:"client_secret,omitempty"`
ClientSecretFile string `yaml:"client_secret_file,omitempty"`
ClientId string `mapstructure:"client_id,omitempty"`
ClientSecret string `mapstructure:"client_secret,omitempty"`
ClientSecretFile string `mapstructure:"client_secret_file,omitempty"`
// path where the tokendb should be stored within the container
TokenDB string `yaml:"token_db,omitempty"`
TokenDB string `mapstructure:"token_db,omitempty"`
// --- optional ---
HTTPTimeout int `yaml:"http_timeout,omitempty"`
HTTPTimeout int `mapstructure:"http_timeout,omitempty"`
// the URL of the docker registry. Used to generate a full docker login command after authentication
RegistryURL string `yaml:"registry_url,omitempty"`
RegistryURL string `mapstructure:"registry_url,omitempty"`
}

// OIDCRefreshTokenResponse is sent by OIDC provider in response to the grant_type=refresh_token request.
Expand Down
4 changes: 2 additions & 2 deletions auth_server/authn/static_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import (
)

type Requirements struct {
Password *api.PasswordString `yaml:"password,omitempty" json:"password,omitempty"`
Labels api.Labels `yaml:"labels,omitempty" json:"labels,omitempty"`
Password *api.PasswordString `mapstructure:"password,omitempty" json:"password,omitempty"`
Labels api.Labels `mapstructure:"labels,omitempty" json:"labels,omitempty"`
}

type staticUsersAuth struct {
Expand Down
18 changes: 9 additions & 9 deletions auth_server/authz/acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,18 @@ import (
type ACL []ACLEntry

type ACLEntry struct {
Match *MatchConditions `yaml:"match"`
Actions *[]string `yaml:"actions,flow"`
Comment *string `yaml:"comment,omitempty"`
Match *MatchConditions `mapstructure:"match"`
Actions *[]string `mapstructure:"actions,flow"`
Comment *string `mapstructure:"comment,omitempty"`
}

type MatchConditions struct {
Account *string `yaml:"account,omitempty" json:"account,omitempty"`
Type *string `yaml:"type,omitempty" json:"type,omitempty"`
Name *string `yaml:"name,omitempty" json:"name,omitempty"`
IP *string `yaml:"ip,omitempty" json:"ip,omitempty"`
Service *string `yaml:"service,omitempty" json:"service,omitempty"`
Labels map[string]string `yaml:"labels,omitempty" json:"labels,omitempty"`
Account *string `mapstructure:"account,omitempty" json:"account,omitempty"`
Type *string `mapstructure:"type,omitempty" json:"type,omitempty"`
Name *string `mapstructure:"name,omitempty" json:"name,omitempty"`
IP *string `mapstructure:"ip,omitempty" json:"ip,omitempty"`
Service *string `mapstructure:"service,omitempty" json:"service,omitempty"`
Labels map[string]string `mapstructure:"labels,omitempty" json:"labels,omitempty"`
}

type aclAuthorizer struct {
Expand Down
6 changes: 3 additions & 3 deletions auth_server/authz/acl_mongo.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ type MongoACLEntry struct {
}

type ACLMongoConfig struct {
MongoConfig *mgo_session.Config `yaml:"dial_info,omitempty"`
Collection string `yaml:"collection,omitempty"`
CacheTTL time.Duration `yaml:"cache_ttl,omitempty"`
MongoConfig *mgo_session.Config `mapstructure:"dial_info,omitempty"`
Collection string `mapstructure:"collection,omitempty"`
CacheTTL time.Duration `mapstructure:"cache_ttl,omitempty"`
}

type aclMongoAuthorizer struct {
Expand Down
4 changes: 2 additions & 2 deletions auth_server/authz/ext_authz.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ import (
)

type ExtAuthzConfig struct {
Command string `yaml:"command"`
Args []string `yaml:"args"`
Command string `mapstructure:"command"`
Args []string `mapstructure:"args"`
}

type ExtAuthzStatus int
Expand Down
Loading