feat: encryption keys in database (#3265)

* enable overwrite of adminUser fields in defaults.yaml

* create schema and table

* cli: create keys

* cli: create keys

* read encryptionkey from db

* merge v2

* file names

* cleanup defaults.yaml

* remove custom errors

* load encryptionKeys on start

* cleanup

* fix merge

* update system defaults

* fix error message
This commit is contained in:
Livio Amstutz
2022-03-14 07:55:09 +01:00
committed by GitHub
parent 7899a0b851
commit 5463244376
57 changed files with 1618 additions and 471 deletions

View File

@@ -4,10 +4,12 @@ import (
_ "embed"
"github.com/caos/logging"
"github.com/spf13/cobra"
"github.com/caos/zitadel/cmd/admin/initialise"
"github.com/caos/zitadel/cmd/admin/key"
"github.com/caos/zitadel/cmd/admin/setup"
"github.com/caos/zitadel/cmd/admin/start"
"github.com/spf13/cobra"
)
func New() *cobra.Command {
@@ -24,6 +26,7 @@ func New() *cobra.Command {
initialise.New(),
setup.New(),
start.New(),
key.New(),
)
return adminCMD

View File

@@ -0,0 +1 @@
CREATE SCHEMA system;

View File

@@ -0,0 +1,6 @@
CREATE TABLE system.encryption_keys (
id TEXT NOT NULL
, key TEXT NOT NULL
, PRIMARY KEY (id)
);

View File

@@ -9,6 +9,8 @@ The sql-files in this folder initialize the ZITADEL database and user. These obj
- 03_grant_user.sql: grants the user created before to have full access to its database. The user needs full access to the database because zitadel makes ddl/dml on runtime
- 04_eventstore.sql: creates the schema needed for eventsourcing
- 05_projections.sql: creates the schema needed to read the data
- files 06_enable_hash_sharded_indexes.sql and 07_events_table.sql must run in the same session
- 06_enable_hash_sharded_indexes.sql enables the [hash sharded index](https://www.cockroachlabs.com/docs/stable/hash-sharded-indexes.html) feature for this session
- 07_events_table.sql creates the table for eventsourcing
- 06_system.sql: creates the schema needed for ZITADEL itself
- 07_encryption_keys_table.sql: creates the table for encryption keys (for event data)
- files 08_enable_hash_sharded_indexes.sql and 09_events_table.sql must run in the same session
- 08_enable_hash_sharded_indexes.sql enables the [hash sharded index](https://www.cockroachlabs.com/docs/stable/hash-sharded-indexes.html) feature for this session
- 09_events_table.sql creates the table for eventsourcing

View File

@@ -4,27 +4,36 @@ import (
"database/sql"
_ "embed"
"github.com/caos/zitadel/internal/database"
"github.com/caos/logging"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/caos/zitadel/internal/database"
)
const (
eventstoreSchema = "eventstore"
projectionsSchema = "projections"
eventstoreSchema = "eventstore"
eventsTable = "events"
projectionsSchema = "projections"
systemSchema = "system"
encryptionKeysTable = "encryption_key"
)
var (
searchEventsTable = "SELECT table_name FROM [SHOW TABLES] WHERE table_name = 'events'"
searchSchema = "SELECT schema_name FROM [SHOW SCHEMAS] WHERE schema_name = $1"
//go:embed sql/06_enable_hash_sharded_indexes.sql
enableHashShardedIdx string
//go:embed sql/07_events_table.sql
createEventsStmt string
//go:embed sql/05_projections.sql
createProjectionsStmt string
searchTable = "SELECT table_name FROM [SHOW TABLES] WHERE table_name = $1"
searchSchema = "SELECT schema_name FROM [SHOW SCHEMAS] WHERE schema_name = $1"
//go:embed sql/04_eventstore.sql
createEventstoreStmt string
//go:embed sql/05_projections.sql
createProjectionsStmt string
//go:embed sql/06_system.sql
createSystemStmt string
//go:embed sql/07_encryption_keys_table.sql
createEncryptionKeysStmt string
//go:embed sql/08_enable_hash_sharded_indexes.sql
enableHashShardedIdx string
//go:embed sql/09_events_table.sql
createEventsStmt string
)
func newZitadel() *cobra.Command {
@@ -47,11 +56,20 @@ Prereqesits:
}
func verifyZitadel(config database.Config) error {
logging.WithFields("database", config.Database).Info("verify database")
db, err := database.Connect(config)
if err != nil {
return err
}
if err := verify(db, exists(searchSchema, systemSchema), exec(createSystemStmt)); err != nil {
return err
}
if err := verify(db, exists(searchTable, encryptionKeysTable), createEncryptionKeys); err != nil {
return err
}
if err := verify(db, exists(searchSchema, projectionsSchema), exec(createProjectionsStmt)); err != nil {
return err
}
@@ -60,13 +78,26 @@ func verifyZitadel(config database.Config) error {
return err
}
if err := verify(db, exists(searchSchema, projectionsSchema), createEvents); err != nil {
if err := verify(db, exists(searchTable, eventsTable), createEvents); err != nil {
return err
}
return db.Close()
}
func createEncryptionKeys(db *sql.DB) error {
tx, err := db.Begin()
if err != nil {
return err
}
if _, err = tx.Exec(createEncryptionKeysStmt); err != nil {
tx.Rollback()
return err
}
return tx.Commit()
}
func createEvents(db *sql.DB) error {
tx, err := db.Begin()
if err != nil {

View File

@@ -71,3 +71,56 @@ func Test_verifyEvents(t *testing.T) {
})
}
}
func Test_verifyEncryptionKeys(t *testing.T) {
type args struct {
db db
}
tests := []struct {
name string
args args
targetErr error
}{
{
name: "unable to begin",
args: args{
db: prepareDB(t,
expectBegin(sql.ErrConnDone),
),
},
targetErr: sql.ErrConnDone,
},
{
name: "create table fails",
args: args{
db: prepareDB(t,
expectBegin(nil),
expectExec(createEncryptionKeysStmt, sql.ErrNoRows),
expectRollback(nil),
),
},
targetErr: sql.ErrNoRows,
},
{
name: "correct",
args: args{
db: prepareDB(t,
expectBegin(nil),
expectExec(createEncryptionKeysStmt, nil),
expectCommit(nil),
),
},
targetErr: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := createEncryptionKeys(tt.args.db.db); !errors.Is(err, tt.targetErr) {
t.Errorf("createEvents() error = %v, want: %v", err, tt.targetErr)
}
if err := tt.args.db.mock.ExpectationsWereMet(); err != nil {
t.Error(err)
}
})
}
}

130
cmd/admin/key/key.go Normal file
View File

@@ -0,0 +1,130 @@
package key
import (
"io"
"os"
"strings"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"sigs.k8s.io/yaml"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/crypto"
cryptoDB "github.com/caos/zitadel/internal/crypto/database"
"github.com/caos/zitadel/internal/database"
)
const (
flagMasterKey = "masterkey"
flagKeyFile = "file"
)
type Config struct {
Database database.Config
}
func New() *cobra.Command {
cmd := &cobra.Command{
Use: "keys",
Short: "manage encryption keys",
}
cmd.PersistentFlags().String(flagMasterKey, "", "masterkey for en/decryption keys")
cmd.AddCommand(newKey())
return cmd
}
func newKey() *cobra.Command {
cmd := &cobra.Command{
Use: "new [keyID=key]... [-f file]",
Short: "create new encryption key(s)",
Long: `create new encryption key(s) (encrypted by the provided master key)
provide key(s) by YAML file and/or by argument
Requirements:
- cockroachdb`,
Example: `new -f keys.yaml
new key1=somekey key2=anotherkey
new -f keys.yaml key2=anotherkey`,
RunE: func(cmd *cobra.Command, args []string) error {
keys, err := keysFromArgs(args)
if err != nil {
return err
}
filePath, _ := cmd.Flags().GetString(flagKeyFile)
if filePath != "" {
file, err := openFile(filePath)
if err != nil {
return err
}
yamlKeys, err := keysFromYAML(file)
if err != nil {
return err
}
keys = append(keys, yamlKeys...)
}
config := new(Config)
if err := viper.Unmarshal(config); err != nil {
return err
}
masterKey, _ := cmd.Flags().GetString(flagMasterKey)
storage, err := keyStorage(config.Database, masterKey)
if err != nil {
return err
}
return storage.CreateKeys(keys...)
},
}
cmd.PersistentFlags().StringP(flagKeyFile, "f", "", "path to keys file")
return cmd
}
func keysFromArgs(args []string) ([]*crypto.Key, error) {
keys := make([]*crypto.Key, len(args))
for i, arg := range args {
key := strings.Split(arg, "=")
if len(key) != 2 {
return nil, caos_errs.ThrowInternal(nil, "KEY-JKd82", "argument is not in the valid format [keyID=key]")
}
keys[i] = &crypto.Key{
ID: key[0],
Value: key[1],
}
}
return keys, nil
}
func keysFromYAML(file io.Reader) ([]*crypto.Key, error) {
data, err := io.ReadAll(file)
if err != nil {
return nil, caos_errs.ThrowInternal(err, "KEY-ajGFr", "unable to extract keys from file")
}
keysYAML := make(map[string]string)
if err = yaml.Unmarshal(data, &keysYAML); err != nil {
return nil, caos_errs.ThrowInternal(err, "KEY-sd34K", "unable to extract keys from file")
}
keys := make([]*crypto.Key, 0, len(keysYAML))
for id, key := range keysYAML {
keys = append(keys, &crypto.Key{
ID: id,
Value: key,
})
}
return keys, nil
}
func openFile(fileName string) (*os.File, error) {
file, err := os.Open(fileName)
if err != nil {
return nil, caos_errs.ThrowInternalf(err, "KEY-asGr2", "failed to open file: %s", fileName)
}
return file, nil
}
func keyStorage(config database.Config, masterKey string) (crypto.KeyStorage, error) {
db, err := database.Connect(config)
if err != nil {
return nil, err
}
return cryptoDB.NewKeyStorage(db, masterKey)
}

161
cmd/admin/key/key_test.go Normal file
View File

@@ -0,0 +1,161 @@
package key
import (
"bytes"
"io"
"reflect"
"testing"
"github.com/stretchr/testify/assert"
caos_errors "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/crypto"
)
func Test_keysFromArgs(t *testing.T) {
type args struct {
args []string
}
type res struct {
keys []*crypto.Key
err func(error) bool
}
tests := []struct {
name string
args args
res res
}{
{
"no args",
args{},
res{
keys: []*crypto.Key{},
},
},
{
"invalid arg",
args{
args: []string{"keyID", "value"},
},
res{
err: caos_errors.IsInternal,
},
},
{
"single arg",
args{
args: []string{"keyID=value"},
},
res{
keys: []*crypto.Key{
{
ID: "keyID",
Value: "value",
},
},
},
},
{
"multiple args",
args{
args: []string{"keyID=value", "keyID2=value2"},
},
res{
keys: []*crypto.Key{
{
ID: "keyID",
Value: "value",
},
{
ID: "keyID2",
Value: "value2",
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := keysFromArgs(tt.args.args)
if tt.res.err == nil {
assert.NoError(t, err)
}
if tt.res.err != nil && !tt.res.err(err) {
t.Errorf("got wrong err: %v ", err)
}
if !reflect.DeepEqual(got, tt.res.keys) {
t.Errorf("keysFromArgs() got = %v, want %v", got, tt.res.keys)
}
})
}
}
func Test_keysFromYAML(t *testing.T) {
type args struct {
file io.Reader
}
type res struct {
keys []*crypto.Key
err func(error) bool
}
tests := []struct {
name string
args args
res res
}{
{
"invalid yaml",
args{
file: bytes.NewReader([]byte("keyID=ds")),
},
res{
err: caos_errors.IsInternal,
},
},
{
"single key",
args{
file: bytes.NewReader([]byte("keyID: value")),
},
res{
keys: []*crypto.Key{
{
ID: "keyID",
Value: "value",
},
},
},
},
{
"multiple keys",
args{
file: bytes.NewReader([]byte("keyID: value\nkeyID2: value2")),
},
res{
keys: []*crypto.Key{
{
ID: "keyID",
Value: "value",
},
{
ID: "keyID2",
Value: "value2",
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := keysFromYAML(tt.args.file)
if tt.res.err == nil {
assert.NoError(t, err)
}
if tt.res.err != nil && !tt.res.err(err) {
t.Errorf("got wrong err: %v ", err)
}
assert.EqualValues(t, got, tt.res.keys)
})
}
}

View File

@@ -0,0 +1,105 @@
package start
import (
"github.com/caos/zitadel/internal/crypto"
caos_errs "github.com/caos/zitadel/internal/errors"
)
var (
defaultKeyIDs = []string{
"domainVerificationKey",
"idpConfigKey",
"oidcKey",
"otpKey",
"smsKey",
"smtpKey",
"userKey",
"csrfCookieKey",
"userAgentCookieKey",
}
)
type encryptionKeys struct {
DomainVerification crypto.EncryptionAlgorithm
IDPConfig crypto.EncryptionAlgorithm
OIDC crypto.EncryptionAlgorithm
OTP crypto.EncryptionAlgorithm
SMS crypto.EncryptionAlgorithm
SMTP crypto.EncryptionAlgorithm
User crypto.EncryptionAlgorithm
CSRFCookieKey []byte
UserAgentCookieKey []byte
OIDCKey []byte
}
func ensureEncryptionKeys(keyConfig *encryptionKeyConfig, keyStorage crypto.KeyStorage) (*encryptionKeys, error) {
keys, err := keyStorage.ReadKeys()
if err != nil {
return nil, nil
}
if len(keys) == 0 {
if err := createDefaultKeys(keyStorage); err != nil {
return nil, err
}
}
encryptionKeys := new(encryptionKeys)
encryptionKeys.DomainVerification, err = crypto.NewAESCrypto(keyConfig.DomainVerification, keyStorage)
if err != nil {
return nil, err
}
encryptionKeys.IDPConfig, err = crypto.NewAESCrypto(keyConfig.IDPConfig, keyStorage)
if err != nil {
return nil, err
}
encryptionKeys.OIDC, err = crypto.NewAESCrypto(keyConfig.OIDC, keyStorage)
if err != nil {
return nil, err
}
key, err := crypto.LoadKey(keyConfig.OIDC.EncryptionKeyID, keyStorage)
if err != nil {
return nil, err
}
encryptionKeys.OIDCKey = []byte(key)
encryptionKeys.OTP, err = crypto.NewAESCrypto(keyConfig.OTP, keyStorage)
if err != nil {
return nil, err
}
encryptionKeys.SMS, err = crypto.NewAESCrypto(keyConfig.SMS, keyStorage)
if err != nil {
return nil, err
}
encryptionKeys.SMTP, err = crypto.NewAESCrypto(keyConfig.SMTP, keyStorage)
if err != nil {
return nil, err
}
encryptionKeys.User, err = crypto.NewAESCrypto(keyConfig.User, keyStorage)
if err != nil {
return nil, err
}
key, err = crypto.LoadKey(keyConfig.CSRFCookieKeyID, keyStorage)
if err != nil {
return nil, err
}
encryptionKeys.CSRFCookieKey = []byte(key)
key, err = crypto.LoadKey(keyConfig.UserAgentCookieKeyID, keyStorage)
if err != nil {
return nil, err
}
encryptionKeys.UserAgentCookieKey = []byte(key)
return encryptionKeys, nil
}
func createDefaultKeys(keyStorage crypto.KeyStorage) error {
keys := make([]*crypto.Key, len(defaultKeyIDs))
for i, keyID := range defaultKeyIDs {
key, err := crypto.NewKey(keyID)
if err != nil {
return err
}
keys[i] = key
}
if err := keyStorage.CreateKeys(keys...); err != nil {
return caos_errs.ThrowInternal(err, "START-aGBq2", "cannot create default keys")
}
return nil
}

View File

@@ -39,6 +39,7 @@ import (
"github.com/caos/zitadel/internal/command"
"github.com/caos/zitadel/internal/config/systemdefaults"
"github.com/caos/zitadel/internal/crypto"
cryptoDB "github.com/caos/zitadel/internal/crypto/database"
"github.com/caos/zitadel/internal/database"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/eventstore"
@@ -52,6 +53,10 @@ import (
"github.com/caos/zitadel/openapi"
)
const (
flagMasterKey = "masterkey"
)
func New() *cobra.Command {
start := &cobra.Command{
Use: "start",
@@ -72,7 +77,8 @@ Requirements:
if err != nil {
return err
}
return startZitadel(config)
masterKey, _ := cmd.Flags().GetString("masterkey")
return startZitadel(config, masterKey)
},
}
bindUint16Flag(start, "port", "port to run ZITADEL on")
@@ -80,6 +86,8 @@ Requirements:
bindStringFlag(start, "externalPort", "port ZITADEL will be exposed on")
bindBoolFlag(start, "externalSecure", "if ZITADEL will be served on HTTPS")
start.PersistentFlags().String(flagMasterKey, "", "masterkey for en/decryption keys")
return start
}
@@ -105,7 +113,7 @@ type startConfig struct {
ExternalDomain string
ExternalSecure bool
Database database.Config
Projections projectionConfig
Projections projection.Config
AuthZ authz.Config
Auth auth_es.Config
Admin admin_es.Config
@@ -117,14 +125,22 @@ type startConfig struct {
AssetStorage static_config.AssetStorageConfig
InternalAuthZ internal_authz.Config
SystemDefaults systemdefaults.SystemDefaults
EncryptionKeys *encryptionKeyConfig
}
type projectionConfig struct {
projection.Config
KeyConfig *crypto.KeyConfig
type encryptionKeyConfig struct {
DomainVerification *crypto.KeyConfig
IDPConfig *crypto.KeyConfig
OIDC *crypto.KeyConfig
OTP *crypto.KeyConfig
SMS *crypto.KeyConfig
SMTP *crypto.KeyConfig
User *crypto.KeyConfig
CSRFCookieKeyID string
UserAgentCookieKeyID string
}
func startZitadel(config *startConfig) error {
func startZitadel(config *startConfig, masterKey string) error {
ctx := context.Background()
keyChan := make(chan interface{})
@@ -132,6 +148,16 @@ func startZitadel(config *startConfig) error {
if err != nil {
return fmt.Errorf("cannot start client for projection: %w", err)
}
keyStorage, err := cryptoDB.NewKeyStorage(dbClient, masterKey)
if err != nil {
return fmt.Errorf("cannot start key storage: %w", err)
}
keys, err := ensureEncryptionKeys(config.EncryptionKeys, keyStorage)
if err != nil {
return err
}
var storage static.Storage
//TODO: enable when storage is implemented again
//if *assetsEnabled {
@@ -142,22 +168,13 @@ func startZitadel(config *startConfig) error {
if err != nil {
return fmt.Errorf("cannot start eventstore for queries: %w", err)
}
smtpPasswordCrypto, err := crypto.NewAESCrypto(config.SystemDefaults.SMTPPasswordVerificationKey)
if err != nil {
return fmt.Errorf("cannot create smtp crypto: %w", err)
}
smsCrypto, err := crypto.NewAESCrypto(config.SystemDefaults.SMSVerificationKey)
if err != nil {
return fmt.Errorf("cannot create smtp crypto: %w", err)
}
queries, err := query.StartQueries(ctx, eventstoreClient, dbClient, config.Projections.Config, config.SystemDefaults, config.Projections.KeyConfig, keyChan, config.InternalAuthZ.RolePermissionMappings)
queries, err := query.StartQueries(ctx, eventstoreClient, dbClient, config.Projections, keys.OIDC, keyChan, config.InternalAuthZ.RolePermissionMappings)
if err != nil {
return fmt.Errorf("cannot start queries: %w", err)
}
authZRepo, err := authz.Start(config.AuthZ, config.SystemDefaults, queries, dbClient, config.OIDC.KeyConfig)
authZRepo, err := authz.Start(config.AuthZ, config.SystemDefaults, queries, dbClient, keys.OIDC)
if err != nil {
return fmt.Errorf("error starting authz repo: %w", err)
}
@@ -166,22 +183,22 @@ func startZitadel(config *startConfig) error {
Origin: http_util.BuildHTTP(config.ExternalDomain, config.ExternalPort, config.ExternalSecure),
DisplayName: "ZITADEL",
}
commands, err := command.StartCommands(eventstoreClient, config.SystemDefaults, config.InternalAuthZ, storage, authZRepo, config.OIDC.KeyConfig, webAuthNConfig, smtpPasswordCrypto, smsCrypto)
commands, err := command.StartCommands(eventstoreClient, config.SystemDefaults, config.InternalAuthZ, storage, authZRepo, webAuthNConfig, keys.IDPConfig, keys.OTP, keys.SMTP, keys.SMS, keys.DomainVerification, keys.OIDC)
if err != nil {
return fmt.Errorf("cannot start commands: %w", err)
}
notification.Start(config.Notification, config.SystemDefaults, commands, queries, dbClient, assets.HandlerPrefix, smtpPasswordCrypto, smsCrypto)
notification.Start(config.Notification, config.SystemDefaults, commands, queries, dbClient, assets.HandlerPrefix, keys.User, keys.SMTP, keys.SMS)
router := mux.NewRouter()
err = startAPIs(ctx, router, commands, queries, eventstoreClient, dbClient, keyChan, config, storage, authZRepo)
err = startAPIs(ctx, router, commands, queries, eventstoreClient, dbClient, keyChan, config, storage, authZRepo, keys)
if err != nil {
return err
}
return listen(ctx, router, config.Port)
}
func startAPIs(ctx context.Context, router *mux.Router, commands *command.Commands, queries *query.Queries, eventstore *eventstore.Eventstore, dbClient *sql.DB, keyChan chan interface{}, config *startConfig, store static.Storage, authZRepo authz_repo.Repository) error {
func startAPIs(ctx context.Context, router *mux.Router, commands *command.Commands, queries *query.Queries, eventstore *eventstore.Eventstore, dbClient *sql.DB, keyChan chan interface{}, config *startConfig, store static.Storage, authZRepo authz_repo.Repository, keys *encryptionKeys) error {
repo := struct {
authz_repo.Repository
*query.Queries
@@ -192,11 +209,7 @@ func startAPIs(ctx context.Context, router *mux.Router, commands *command.Comman
verifier := internal_authz.Start(repo)
apis := api.New(config.Port, router, &repo, config.InternalAuthZ, config.ExternalSecure)
userEncryptionAlgorithm, err := crypto.NewAESCrypto(config.SystemDefaults.UserVerificationKey)
if err != nil {
return nil
}
authRepo, err := auth_es.Start(config.Auth, config.SystemDefaults, commands, queries, dbClient, config.OIDC.KeyConfig, assets.HandlerPrefix, userEncryptionAlgorithm)
authRepo, err := auth_es.Start(config.Auth, config.SystemDefaults, commands, queries, dbClient, assets.HandlerPrefix, keys.OIDC, keys.User)
if err != nil {
return fmt.Errorf("error starting auth repo: %w", err)
}
@@ -204,25 +217,25 @@ func startAPIs(ctx context.Context, router *mux.Router, commands *command.Comman
if err != nil {
return fmt.Errorf("error starting admin repo: %w", err)
}
if err := apis.RegisterServer(ctx, admin.CreateServer(commands, queries, adminRepo, config.SystemDefaults.Domain, assets.HandlerPrefix, userEncryptionAlgorithm)); err != nil {
if err := apis.RegisterServer(ctx, admin.CreateServer(commands, queries, adminRepo, config.SystemDefaults.Domain, assets.HandlerPrefix, keys.User)); err != nil {
return err
}
if err := apis.RegisterServer(ctx, management.CreateServer(commands, queries, config.SystemDefaults, assets.HandlerPrefix, userEncryptionAlgorithm)); err != nil {
if err := apis.RegisterServer(ctx, management.CreateServer(commands, queries, config.SystemDefaults, assets.HandlerPrefix, keys.User)); err != nil {
return err
}
if err := apis.RegisterServer(ctx, auth.CreateServer(commands, queries, authRepo, config.SystemDefaults, assets.HandlerPrefix, userEncryptionAlgorithm)); err != nil {
if err := apis.RegisterServer(ctx, auth.CreateServer(commands, queries, authRepo, config.SystemDefaults, assets.HandlerPrefix, keys.User)); err != nil {
return err
}
apis.RegisterHandler(assets.HandlerPrefix, assets.NewHandler(commands, verifier, config.InternalAuthZ, id.SonyFlakeGenerator, store, queries))
userAgentInterceptor, err := middleware.NewUserAgentHandler(config.UserAgentCookie, config.ExternalDomain, id.SonyFlakeGenerator, config.ExternalSecure)
userAgentInterceptor, err := middleware.NewUserAgentHandler(config.UserAgentCookie, keys.UserAgentCookieKey, config.ExternalDomain, id.SonyFlakeGenerator, config.ExternalSecure)
if err != nil {
return err
}
issuer := oidc.Issuer(config.ExternalDomain, config.ExternalPort, config.ExternalSecure)
oidcProvider, err := oidc.NewProvider(ctx, config.OIDC, issuer, login.DefaultLoggedOutPath, commands, queries, authRepo, config.SystemDefaults.KeyConfig, eventstore, dbClient, keyChan, userAgentInterceptor)
oidcProvider, err := oidc.NewProvider(ctx, config.OIDC, issuer, login.DefaultLoggedOutPath, commands, queries, authRepo, config.SystemDefaults.KeyConfig, keys.OIDC, keys.OIDCKey, eventstore, dbClient, keyChan, userAgentInterceptor)
if err != nil {
return fmt.Errorf("unable to start oidc provider: %w", err)
}
@@ -238,13 +251,14 @@ func startAPIs(ctx context.Context, router *mux.Router, commands *command.Comman
if err != nil {
return fmt.Errorf("unable to get client_id for console: %w", err)
}
c, err := console.Start(config.Console, config.ExternalDomain, http_util.BuildHTTP(config.ExternalDomain, config.ExternalPort, config.ExternalSecure), issuer, consoleID)
baseURL := http_util.BuildHTTP(config.ExternalDomain, config.ExternalPort, config.ExternalSecure)
c, err := console.Start(config.Console, config.ExternalDomain, baseURL, issuer, consoleID)
if err != nil {
return fmt.Errorf("unable to start console: %w", err)
}
apis.RegisterHandler(console.HandlerPrefix, c)
l, err := login.CreateLogin(config.Login, commands, queries, authRepo, store, config.SystemDefaults, console.HandlerPrefix, config.ExternalDomain, oidc.AuthCallback, config.ExternalSecure, userAgentInterceptor, userEncryptionAlgorithm)
l, err := login.CreateLogin(config.Login, commands, queries, authRepo, store, config.SystemDefaults, console.HandlerPrefix, config.ExternalDomain, baseURL, oidc.AuthCallback, config.ExternalSecure, userAgentInterceptor, keys.User, keys.IDPConfig, keys.CSRFCookieKey)
if err != nil {
return fmt.Errorf("unable to start login: %w", err)
}