diff --git a/.gitignore b/.gitignore index 8436fbf..8ef9453 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ *.crt download curlresponse.txt +create-schema.sql # License downloads curity-book-cli* @@ -44,5 +45,4 @@ resources/apigateway/helm-values.yaml ## SPIFFE chapter-10-workload-identities/base/authorizationserver/resources/signing* -chapter-10-workload-identities/base/authorizationserver/resources/postgres-schema.sql !chapter-10-workload-identities/demoapi/gradle/wrapper/gradle-wrapper.jar diff --git a/chapter-09-entitlements/README.md b/chapter-09-entitlements/README.md index 63def68..622b960 100644 --- a/chapter-09-entitlements/README.md +++ b/chapter-09-entitlements/README.md @@ -166,8 +166,8 @@ Both API requests are then authorized, and responses include different authorize The authorization rules are based on these data relationships: -- [Dana's user account](https://github.com/curityio/cloud-native-oauth-security-examples/tree/main/resources/authorizationserver/data-backup.sql#L339) has `customer_id=2099` and `role=customer`. -- [Kims's user account](https://github.com/curityio/cloud-native-oauth-security-examples/tree/main/resources/authorizationserver/data-backup.sql#L340) has a `role=admin` and `region=USA`. +- [Dana's user account](https://github.com/curityio/cloud-native-oauth-security-examples/tree/main/resources/authorizationserver/user-import.sql#5) has `customer_id=2099` and `role=customer`. +- [Kims's user account](https://github.com/curityio/cloud-native-oauth-security-examples/tree/main/resources/authorizationserver/user-import.sql#L10) has a `role=admin` and `region=USA`. - The client requests an [order with an ID of 20882](https://github.com/curityio/cloud-native-oauth-security-examples/tree/main/chapter-12-platform-specific-apps/console-app/src/index.ts#L19). - The [order 20882 resource](https://github.com/curityio/cloud-native-oauth-security-examples/tree/main/chapter-05-secure-api-development/data/orderSummary.json#L11) has `customer_id=3044` and `region=USA`. - Dana is not authorized to access the order since it is for another customer. diff --git a/chapter-10-workload-identities/base/authorizationserver/install.sh b/chapter-10-workload-identities/base/authorizationserver/install.sh index f88b8cb..11073cf 100755 --- a/chapter-10-workload-identities/base/authorizationserver/install.sh +++ b/chapter-10-workload-identities/base/authorizationserver/install.sh @@ -50,11 +50,23 @@ if [ $? -ne 0 ]; then fi # -# Create a configmap for the database schema of the authorization server +# Copy in the latest schema creation script from the Curity Docker image +# +docker pull curity.azurecr.io/curity/idsvr +docker run --name curity -d -e PASSWORD=Password1 curity.azurecr.io/curity/idsvr +docker cp curity:/opt/idsvr/etc/postgres-create_database.sql ./create-schema.sql +docker rm --force curity 1>/dev/null +if [ ! -f ./create-schema.sql ]; then + echo 'Problem encountered getting the schema creation script' + exit 1 +fi + # -kubectl -n authorizationserver create configmap postgres-configmap --from-file='resources/postgres-schema.sql' +# Create a configmap with the schema creation script +# +kubectl -n authorizationserver create configmap postgres-configmap --from-file='create-schema.sql' if [ $? -ne 0 ]; then - echo '*** Problem encountered creating the postgres config map' + echo 'Problem encountered creating the postgres configmap' exit 1 fi diff --git a/chapter-10-workload-identities/base/authorizationserver/protect-secrets.sh b/chapter-10-workload-identities/base/authorizationserver/protect-secrets.sh index 06a5a35..696900a 100755 --- a/chapter-10-workload-identities/base/authorizationserver/protect-secrets.sh +++ b/chapter-10-workload-identities/base/authorizationserver/protect-secrets.sh @@ -43,8 +43,8 @@ ADMIN_PASSWORD=$(openssl passwd -5 $ADMIN_PASSWORD_RAW) # # Plaintext database details # -DB_NAME='idsvrdb' -DB_USER='idsvruser' +DB_NAME='idsvr' +DB_USER='postgres' DB_PASSWORD_RAW='Password1' DB_CONNECTION_RAW="jdbc:postgresql://postgres-svc/$DB_NAME" diff --git a/chapter-10-workload-identities/base/authorizationserver/resources/postgres.yaml b/chapter-10-workload-identities/base/authorizationserver/resources/postgres.yaml index d94456c..45de743 100644 --- a/chapter-10-workload-identities/base/authorizationserver/resources/postgres.yaml +++ b/chapter-10-workload-identities/base/authorizationserver/resources/postgres.yaml @@ -38,22 +38,22 @@ spec: spec: containers: - name: postgres - image: postgres:17.6 + image: postgres:18.4 volumeMounts: - mountPath: /docker-entrypoint-initdb.d - name: init-script + name: init-scripts readOnly: true env: - name: POSTGRES_USER - value: idsvruser + value: postgres - name: POSTGRES_PASSWORD value: Password1 - name: POSTGRES_DB - value: idsvrdb + value: idsvr ports: - containerPort: 5432 name: postgres volumes: - - name: init-script + - name: init-scripts configMap: name: postgres-configmap diff --git a/chapter-10-workload-identities/base/service-mesh/istiod-helm-values.yaml b/chapter-10-workload-identities/base/service-mesh/istiod-helm-values.yaml index 729b561..affb601 100644 --- a/chapter-10-workload-identities/base/service-mesh/istiod-helm-values.yaml +++ b/chapter-10-workload-identities/base/service-mesh/istiod-helm-values.yaml @@ -1,13 +1,10 @@ -######################################################################################### +############################################################################################################## # Parameters for the istiod Helm chart, which injects sidecars into workloads # - https://artifacthub.io/packages/helm/istio-official/istiod?modal=values # -# Implement the technique from the istio-spire-config.yaml file: -# - https://github.com/istio/istio/tree/master/samples/security/spire -# -# - Set the trust domain for the mesh -# - Mount the SPIFFE CSI driver so that sidecars and the gateway receive SVIDs from SPIRE -######################################################################################### +# Integrate Istio with SPIRE, by mounting the CSI driver at the path from which Istio gets workload identities +# - https://istio.io/latest/docs/ops/integrations/spire/#install-istio +############################################################################################################## meshConfig: trustDomain: democluster.internal @@ -15,6 +12,12 @@ sidecarInjectorWebhook: templates: spire: | spec: + initContainers: + - name: istio-proxy + volumeMounts: + - name: workload-socket + mountPath: /run/secrets/workload-spiffe-uds + readOnly: true volumes: - name: workload-socket csi: diff --git a/chapter-13-browser-based-apps/backend-for-frontend/oauth-agent/package-lock.json b/chapter-13-browser-based-apps/backend-for-frontend/oauth-agent/package-lock.json index ca69f00..fb3bc3a 100644 --- a/chapter-13-browser-based-apps/backend-for-frontend/oauth-agent/package-lock.json +++ b/chapter-13-browser-based-apps/backend-for-frontend/oauth-agent/package-lock.json @@ -515,7 +515,6 @@ "integrity": "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^5.0.0", diff --git a/resources/authorizationserver/data-backup.sql b/resources/authorizationserver/data-backup.sql deleted file mode 100644 index 68c6db1..0000000 --- a/resources/authorizationserver/data-backup.sql +++ /dev/null @@ -1,545 +0,0 @@ - --- While Postgres has native support for UUID's, an extension is needed for generating them. --- This extension comes bundled with most installations of Postgres but if not must be installed separately --- --- https://dba.stackexchange.com/questions/122623/default-value-for-uuid-column-in-postgres --- -CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; - - -/* Token Store : table delegations */ - -CREATE TABLE delegations ( - id VARCHAR(40) PRIMARY KEY, - tenant_id VARCHAR(64) NULL, - owner VARCHAR(128) NOT NULL, - created BIGINT NOT NULL, - expires BIGINT NOT NULL, - scope VARCHAR(1000) NULL, - scope_claims TEXT NULL, - client_id VARCHAR(128) NOT NULL, - redirect_uri VARCHAR(512) NULL, - status VARCHAR(16) NOT NULL, - claims TEXT NULL, - authentication_attributes TEXT NULL, - authorization_code_hash VARCHAR(89) NULL -); - -CREATE INDEX IDX_DELEGATIONS_CLIENT_ID ON delegations (client_id ASC); -CREATE INDEX IDX_DELEGATIONS_STATUS ON delegations (status ASC); -CREATE INDEX IDX_DELEGATIONS_EXPIRES ON delegations (expires ASC); -CREATE INDEX IDX_DELEGATIONS_OWNER ON delegations (owner ASC); -CREATE INDEX IDX_DELEGATIONS_AUTHORIZATION_CODE_HASH ON delegations (authorization_code_hash ASC); - -COMMENT ON COLUMN delegations.id IS 'Unique identifier'; -COMMENT ON COLUMN delegations.tenant_id IS 'The tenant ID of this delegation'; -COMMENT ON COLUMN delegations.owner IS 'Subject for whom the delegation is issued'; -COMMENT ON COLUMN delegations.expires IS 'Moment when delegation expires, as measured in number of seconds since epoch'; -COMMENT ON COLUMN delegations.scope IS 'Space delimited list of scope values'; -COMMENT ON COLUMN delegations.scope_claims IS 'JSON with the scope-claims configuration at the time of delegation issuance'; -COMMENT ON COLUMN delegations.client_id IS 'Reference to a client; non-enforced'; -COMMENT ON COLUMN delegations.redirect_uri IS 'Optional value for the redirect_uri parameter, when provided in a request for delegation'; -COMMENT ON COLUMN delegations.status IS 'Status of the delegation instance, from {''issued'', ''revoked''}'; -COMMENT ON COLUMN delegations.claims IS 'Optional JSON that contains a list of claims that are part of the delegation'; -COMMENT ON COLUMN delegations.authentication_attributes IS 'The JSON-serialized AuthenticationAttributes established for this delegation'; -COMMENT ON COLUMN delegations.authorization_code_hash IS 'A hash of the authorization code that was provided when this delegation was issued.'; - - -/* Token Store : table tokens */ - -CREATE TABLE tokens ( - token_hash VARCHAR(89) NOT NULL PRIMARY KEY, - id VARCHAR(64) NULL, - delegations_id VARCHAR(40) NOT NULL , - purpose VARCHAR(32) NOT NULL, - usage VARCHAR(8) NOT NULL, - format VARCHAR(32) NOT NULL, - created BIGINT NOT NULL, - expires BIGINT NOT NULL, - scope VARCHAR(1000)NULL, - scope_claims TEXT NULL, - status VARCHAR(16) NOT NULL, - issuer VARCHAR(200) NOT NULL, - subject VARCHAR(64) NOT NULL, - audience VARCHAR(512) NULL, - not_before BIGINT NULL, - claims TEXT NULL, - meta_data TEXT NULL -); - -CREATE INDEX IDX_TOKENS_ID ON tokens (id); -CREATE INDEX IDX_TOKENS_STATUS ON tokens (status ASC); -CREATE INDEX IDX_TOKENS_EXPIRES ON tokens (expires ASC); - -COMMENT ON COLUMN tokens.token_hash IS 'Base64 encoded sha-512 hash of the token value.'; -COMMENT ON COLUMN tokens.id IS 'Identifier of the token, when it exists; this can be the value from the ''jti''-claim of a JWT, etc. Opaque tokens do not have an id.'; -COMMENT ON COLUMN tokens.delegations_id IS 'Reference to the delegation instance that underlies the token'; -COMMENT ON COLUMN tokens.purpose IS 'Purpose of the token, i.e. ''nonce'', ''accesstoken'', ''refreshtoken'', ''custom'', etc.'; -COMMENT ON COLUMN tokens.usage IS 'Indication whether the token is a bearer or proof token, from {"bearer", "proof"}'; -COMMENT ON COLUMN tokens.format IS 'The format of the token, i.e. ''opaque'', ''jwt'', etc.'; -COMMENT ON COLUMN tokens.created IS 'Moment when token record is created, as measured in number of seconds since epoch'; -COMMENT ON COLUMN tokens.expires IS 'Moment when token expires, as measured in number of seconds since epoch'; -COMMENT ON COLUMN tokens.scope IS 'Space delimited list of scope values'; -COMMENT ON COLUMN tokens.scope_claims IS 'Space delimited list of scope-claims values'; -COMMENT ON COLUMN tokens.status IS 'Status of the token from {''issued'', ''used'', ''revoked''}'; -COMMENT ON COLUMN tokens.issuer IS 'Optional name of the issuer of the token (jwt.iss)'; -COMMENT ON COLUMN tokens.subject IS 'Optional subject of the token (jwt.sub)'; -COMMENT ON COLUMN tokens.audience IS 'Space separated list of audiences for the token (jwt.aud)'; -COMMENT ON COLUMN tokens.not_before IS 'Moment before which the token is not valid, as measured in number of seconds since epoch (jwt.nbf)'; -COMMENT ON COLUMN tokens.claims IS 'Optional JSON-blob that contains a list of claims that are part of the token'; - - -CREATE TABLE nonces ( - token VARCHAR(64) NOT NULL PRIMARY KEY, - reference_data TEXT NOT NULL, - created BIGINT NOT NULL, - ttl BIGINT NOT NULL, - consumed BIGINT NULL, - status VARCHAR(16) NOT NULL DEFAULT 'issued' -); - -COMMENT ON COLUMN nonces.token IS 'Value issued as random nonce'; -COMMENT ON COLUMN nonces.reference_data IS 'Value that is referenced by the nonce value'; -COMMENT ON COLUMN nonces.created IS 'Moment when nonce record is created, as measured in number of seconds since epoch'; -COMMENT ON COLUMN nonces.ttl IS 'Time To Live, period in seconds since created after which the nonce expires'; -COMMENT ON COLUMN nonces.consumed IS 'Moment when nonce was consumed, as measured in number of seconds since epoch'; -COMMENT ON COLUMN nonces.status IS 'Status of the nonce from {''issued'', ''revoked'', ''used''}'; - - -CREATE TABLE accounts ( - account_id VARCHAR(64) PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(), - tenant_id VARCHAR(64), - username VARCHAR(64) NOT NULL, - email VARCHAR(64), - phone VARCHAR(32), - attributes JSONB, - active SMALLINT NOT NULL DEFAULT 0, - created BIGINT NOT NULL, - updated BIGINT NOT NULL -); - -CREATE UNIQUE INDEX IDX_ACCOUNTS_TENANT_USERNAME ON accounts (tenant_id, username); -CREATE UNIQUE INDEX IDX_ACCOUNTS_TENANT_PHONE ON accounts (tenant_id, phone); -CREATE UNIQUE INDEX IDX_ACCOUNTS_TENANT_EMAIL ON accounts (tenant_id, email); - --- Indexes enforcing uniqueness of username, phone, email for default tenant. -CREATE UNIQUE INDEX IDX_ACCOUNTS_TENANT_USERNAME_DEFAULT ON accounts(username) WHERE tenant_id IS NULL; -CREATE UNIQUE INDEX IDX_ACCOUNTS_TENANT_PHONE_DEFAULT ON accounts(phone) WHERE tenant_id IS NULL; -CREATE UNIQUE INDEX IDX_ACCOUNTS_TENANT_EMAIL_DEFAULT ON accounts(email) WHERE tenant_id IS NULL; - -CREATE INDEX IDX_ACCOUNTS_ATTRIBUTES_NAME ON accounts USING GIN ( (attributes->'name') ); - -COMMENT ON COLUMN accounts.account_id IS 'Account id, or username, of this account. Unique.'; -COMMENT ON COLUMN accounts.tenant_id IS 'The tenant ID of this account. Unique in combination with username, phone, email.'; -COMMENT ON COLUMN accounts.username IS 'The username of this account. Unique in combination with tenant_id.'; -COMMENT ON COLUMN accounts.email IS 'The associated email address. Unique in combination with tenant_id. Optional'; -COMMENT ON COLUMN accounts.phone IS 'The phone number of the account owner. Unique in combination with tenant_id. Optional'; -COMMENT ON COLUMN accounts.attributes IS 'Key/value map of additional attributes associated with the account.'; -COMMENT ON COLUMN accounts.active IS 'Indicates if this account has been activated or not. Activation is usually via email or sms.'; -COMMENT ON COLUMN accounts.created IS 'Time since epoch of account creation, in seconds'; -COMMENT ON COLUMN accounts.updated IS 'Time since epoch of latest account update, in seconds'; - - -CREATE TABLE linked_accounts ( - account_id VARCHAR(64) NOT NULL, - tenant_id VARCHAR(64), - linked_account_id VARCHAR(64) NOT NULL, - linked_account_domain_name VARCHAR(64) NOT NULL, - linking_account_manager VARCHAR(128), - created TIMESTAMP NOT NULL, - - PRIMARY KEY (account_id, linked_account_id, linked_account_domain_name) -); - -CREATE UNIQUE INDEX IDX_LINKED_ACCOUNTS_TENANT_ACCOUNT_DOMAIN ON linked_accounts (tenant_id, linked_account_id, linked_account_domain_name); -CREATE UNIQUE INDEX IDX_LINKED_ACCOUNTS_TENANT_ACCOUNT_DOMAIN_DEFAULT ON linked_accounts (linked_account_id, linked_account_domain_name) WHERE tenant_id IS NULL; - -COMMENT ON COLUMN linked_accounts.account_id IS 'Account ID, typically a global one, of the account being linked from (the linker)'; -COMMENT ON COLUMN linked_accounts.tenant_id IS 'The tenant ID of this linked account'; -COMMENT ON COLUMN linked_accounts.linked_account_id IS 'Account ID, typically a local or legacy one, of the account being linked (the linkee)'; -COMMENT ON COLUMN linked_accounts.linked_account_domain_name IS 'The domain (i.e., organizational group or realm) of the account being linked'; - - -CREATE TABLE credentials ( - id VARCHAR(36) PRIMARY KEY DEFAULT uuid_generate_v4(), - tenant_id VARCHAR(64), - subject VARCHAR(64) NOT NULL, - password VARCHAR(128) NOT NULL, - attributes JSONB NOT NULL, - created TIMESTAMP NOT NULL, - updated TIMESTAMP NOT NULL -); - -CREATE UNIQUE INDEX IDX_CREDENTIALS_TENANT_SUBJECT ON credentials (tenant_id, subject); -CREATE UNIQUE INDEX IDX_CREDENTIALS_TENANT_SUBJECT_DEFAULT ON credentials (subject) WHERE tenant_id IS NULL; - -COMMENT ON COLUMN credentials.id IS 'ID of this credential (unique)'; -COMMENT ON COLUMN credentials.tenant_id IS 'The tenant ID of this credential'; -COMMENT ON COLUMN credentials.subject IS 'The subject of this credential (unique to a tenant)'; -COMMENT ON COLUMN credentials.password IS 'The hashed password'; -COMMENT ON COLUMN credentials.attributes IS 'Key/value map of additional attributes associated with the credential'; -COMMENT ON COLUMN credentials.created IS 'When this credential was created'; -COMMENT ON COLUMN credentials.updated IS 'When this credential was last updated'; - - -CREATE TABLE sessions ( - id VARCHAR(64) NOT NULL PRIMARY KEY, - session_data TEXT NOT NULL, - expires BIGINT NOT NULL -); - -CREATE INDEX IDX_SESSIONS_ID ON sessions (id ASC); -CREATE INDEX IDX_SESSIONS_ID_EXPIRES ON sessions (id, expires); - - -COMMENT ON COLUMN sessions.id IS 'id given to the session'; -COMMENT ON COLUMN sessions.session_data IS 'Value that is referenced by the session id'; -COMMENT ON COLUMN sessions.expires IS 'Moment when session record expires, as measured in number of seconds since epoch'; - - -CREATE TABLE devices ( - id VARCHAR(64) PRIMARY KEY NOT NULL, - device_id VARCHAR(256), - tenant_id VARCHAR(64), - account_id VARCHAR(256), - external_id VARCHAR(32), - alias VARCHAR(30), - form_factor VARCHAR(10), - device_type VARCHAR(50), - owner VARCHAR(256), - attributes JSONB, - expires BIGINT, - created BIGINT NOT NULL, - updated BIGINT NOT NULL -); - -CREATE UNIQUE INDEX IDX_DEVICES_TENANT_ACCOUNT_ID_DEVICE_ID ON devices (tenant_id, account_id ASC, device_id ASC); -CREATE UNIQUE INDEX IDX_DEVICES_TENANT_ACCOUNT_ID_DEVICE_ID_DEFAULT ON devices (account_id ASC, device_id ASC) WHERE tenant_id IS NULL; -CREATE INDEX IDX_DEVICE_ID ON devices (device_id ASC); - -COMMENT ON COLUMN devices.id IS 'Unique ID of the device'; -COMMENT ON COLUMN devices.device_id IS 'The device ID that identifies the physical device'; -COMMENT ON COLUMN devices.tenant_id IS 'The tenant ID of this device'; -COMMENT ON COLUMN devices.account_id IS 'The user account ID that is associated with the device'; -COMMENT ON COLUMN devices.alias IS 'The user-recognizable name or mnemonic identifier of the device (e.g., my work iPhone)'; -COMMENT ON COLUMN devices.form_factor IS 'The type or form of device (e.g., laptop, phone, tablet, etc.)'; -COMMENT ON COLUMN devices.device_type IS 'The device type (i.e., make, manufacturer, provider, class)'; -COMMENT ON COLUMN devices.owner IS 'The owner of the device. This is the user who has administrative rights on the device'; -COMMENT ON COLUMN devices.attributes IS 'Key/value map of custom attributes associated with the device.'; -COMMENT ON COLUMN devices.expires IS 'Time since epoch of device expiration, in seconds'; -COMMENT ON COLUMN devices.created IS 'Time since epoch of device creation, in seconds'; -COMMENT ON COLUMN devices.updated IS 'Time since epoch of latest device update, in seconds'; - - --- This number is user-supplied and may not be a phone number. It can be a part number or employer-provided unit number. --- It may also be blank. In any event, it is only used to provide the user with an extra queue as to which device this --- one refers. Unlike the phone number in the account table, this one is _not_ verified in any way. -COMMENT ON COLUMN devices.external_id IS 'The phone or other identifying number of the device (if it has one)'; - - -CREATE TABLE audit ( - id VARCHAR(64) PRIMARY KEY, - instant TIMESTAMP NOT NULL, - event_instant VARCHAR(64) NOT NULL, - server VARCHAR(255) NOT NULL, - message TEXT NOT NULL, - event_type VARCHAR(48) NOT NULL, - subject VARCHAR(128), - client VARCHAR(128), - resource VARCHAR(128), - authenticated_subject VARCHAR(128), - authenticated_client VARCHAR(128), - acr VARCHAR(128), - endpoint VARCHAR(255), - session VARCHAR(128) -); - -COMMENT ON COLUMN audit.id IS 'Unique ID of the log message'; -COMMENT ON COLUMN audit.instant IS 'Moment that the event was logged'; -COMMENT ON COLUMN audit.event_instant IS 'Moment that the event occurred'; -COMMENT ON COLUMN audit.server IS 'The server node where the event occurred'; -COMMENT ON COLUMN audit.message IS 'Message describing the event'; -COMMENT ON COLUMN audit.event_type IS 'Type of event that the message is about'; -COMMENT ON COLUMN audit.subject IS 'The subject (i.e., user) effected by the event'; -COMMENT ON COLUMN audit.client IS 'The client ID effected by the event'; -COMMENT ON COLUMN audit.resource IS 'The resource ID effected by the event'; -COMMENT ON COLUMN audit.authenticated_subject IS 'The authenticated subject (i.e., user) effected by the event'; -COMMENT ON COLUMN audit.authenticated_client IS 'The authenticated client effected by the event'; -COMMENT ON COLUMN audit.acr IS 'The ACR used to authenticate the subject (i.e., user)'; -COMMENT ON COLUMN audit.endpoint IS 'The endpoint where the event was triggered'; -COMMENT ON COLUMN audit.session IS 'The session ID in which the event was triggered'; - - -CREATE TABLE dynamically_registered_clients ( - client_id VARCHAR(64) NOT NULL PRIMARY KEY, - client_secret VARCHAR(128), - instance_of_client VARCHAR(64) NULL, - created TIMESTAMP NOT NULL, - updated TIMESTAMP NOT NULL, - initial_client VARCHAR(64) NULL, - authenticated_user VARCHAR(64) NULL, - attributes JSONB NOT NULL DEFAULT '{}', - status VARCHAR(12) NOT NULL DEFAULT 'active', - scope TEXT NULL, - redirect_uris TEXT NULL, - grant_types VARCHAR(500) NULL -); - -CREATE INDEX IDX_DRC_INSTANCE_OF_CLIENT ON dynamically_registered_clients(instance_of_client); -CREATE INDEX IDX_DRC_ATTRIBUTES ON dynamically_registered_clients USING GIN (attributes); -CREATE INDEX IDX_DRC_CREATED ON dynamically_registered_clients(created); -CREATE INDEX IDX_DRC_STATUS ON dynamically_registered_clients(status); -CREATE INDEX IDX_DRC_AUTHENTICATED_USER ON dynamically_registered_clients(authenticated_user); - -COMMENT ON COLUMN dynamically_registered_clients.client_id IS 'The client ID of this client instance'; -COMMENT ON COLUMN dynamically_registered_clients.created IS 'When this client was originally created (in UTC time)'; -COMMENT ON COLUMN dynamically_registered_clients.updated IS 'When this client was last updated (in UTC time)'; -COMMENT ON COLUMN dynamically_registered_clients.initial_client IS 'In case the user authenticated, this value contains a client_id value of the initial token. If the initial token was issued through a client credentials-flow, the initial_client value is set to the client that authenticated. Registration without initial token (i.e. with no authentication) will result in a null value for initial_client'; -COMMENT ON COLUMN dynamically_registered_clients.authenticated_user IS 'In case a user authenticated (through a client), this value contains the sub value of the initial token'; -COMMENT ON COLUMN dynamically_registered_clients.attributes IS 'Arbitrary attributes tied to this client'; -COMMENT ON COLUMN dynamically_registered_clients.status IS 'The current status of the client, allowed values are "active", "inactive" and "revoked"'; -COMMENT ON COLUMN dynamically_registered_clients.scope IS 'Space separated list of scopes defined for this client (non-templatized clients only)'; -COMMENT ON COLUMN dynamically_registered_clients.redirect_uris IS 'Space separated list of redirect URI''s defined for this client (non-templatized clients only)'; -COMMENT ON COLUMN dynamically_registered_clients.grant_types IS 'Space separated list of grant types defined for this client (non-templatized clients only)'; - -CREATE TABLE database_clients -( - client_id VARCHAR(64) NOT NULL, - profile_id VARCHAR(64) NOT NULL, - client_name VARCHAR(128) NULL, - created TIMESTAMP NOT NULL, - updated TIMESTAMP NOT NULL, - owner VARCHAR(128) NOT NULL, - status VARCHAR(16) NOT NULL DEFAULT 'active', - client_metadata JSONB NOT NULL DEFAULT '{}', - configuration_references JSONB NOT NULL DEFAULT '{}', - attributes JSONB NOT NULL DEFAULT '{}', - - PRIMARY KEY (client_id, profile_id) -); - -COMMENT ON COLUMN database_clients.client_id IS 'The client ID of this client instance'; -COMMENT ON COLUMN database_clients.profile_id IS 'The profile ID owning this client instance'; -COMMENT ON COLUMN database_clients.client_name IS 'The optional database client display name'; -COMMENT ON COLUMN database_clients.created IS 'When this client was originally created (in UTC time)'; -COMMENT ON COLUMN database_clients.updated IS 'When this client was last updated (in UTC time)'; -COMMENT ON COLUMN database_clients.owner IS 'The owner of the database client. This is the user or client who has administrative rights on the database client'; -COMMENT ON COLUMN database_clients.status IS 'The current status of the client, allowed values are "active", "inactive" and "revoked"'; -COMMENT ON COLUMN database_clients.client_metadata IS 'Metadata, as a JSON document, tied to this client, especially tags categorizing it'; -COMMENT ON COLUMN database_clients.configuration_references IS 'JSON document with all attributes referencing an item in the configuration'; -COMMENT ON COLUMN database_clients.attributes IS 'Canonical object representing this client'; - -CREATE INDEX IDX_DATABASE_CLIENTS_PROFILE_ID ON database_clients (profile_id ASC); -CREATE INDEX IDX_DATABASE_CLIENTS_CLIENT_NAME ON database_clients (client_name ASC); -CREATE INDEX IDX_DATABASE_CLIENTS_OWNER ON database_clients (owner ASC); -CREATE INDEX IDX_DATABASE_CLIENTS_METADATA_TAGS ON database_clients USING GIN ((client_metadata -> 'tags') jsonb_path_ops); -CREATE INDEX IDX_DATABASE_CLIENTS_METADATA_TAGS_NULL ON database_clients (client_metadata) WHERE client_metadata->'tags' IS NULL; - -CREATE TABLE buckets ( - id VARCHAR(64) NOT NULL DEFAULT uuid_generate_v4(), - subject VARCHAR(128) NOT NULL, - purpose VARCHAR(64) NOT NULL, - tenant_id VARCHAR(64), - attributes JSONB NOT NULL, - created TIMESTAMP NOT NULL, - updated TIMESTAMP NOT NULL, - expires TIMESTAMP NULL, - - PRIMARY KEY (id) -); - -CREATE UNIQUE INDEX IDX_BUCKETS_TENANT_SUBJECT_PURPOSE on buckets (tenant_id, subject, purpose); -CREATE UNIQUE INDEX IDX_BUCKETS_TENANT_SUBJECT_PURPOSE_DEFAULT on buckets (subject, purpose) WHERE tenant_id IS NULL; - -CREATE INDEX IDX_BUCKETS_ATTRIBUTES ON buckets USING GIN (attributes); -CREATE INDEX "IDX_BUCKETS_EXPIRES" ON buckets (expires); - -COMMENT ON COLUMN buckets.id IS 'Unique ID of the bucket'; -COMMENT ON COLUMN buckets.subject IS 'The subject that together with the purpose identify this bucket'; -COMMENT ON COLUMN buckets.purpose IS 'The purpose of this bucket, eg. "login_attempt_counter"'; -COMMENT ON COLUMN buckets.tenant_id IS 'The tenant ID of this bucket'; -COMMENT ON COLUMN buckets.attributes IS 'All attributes stored for this subject/purpose'; -COMMENT ON COLUMN buckets.created IS 'When this bucket was created'; -COMMENT ON COLUMN buckets.updated IS 'When this bucket was last updated'; -COMMENT ON COLUMN buckets.expires IS 'When this bucket expires, or NULL if it does not expire'; - -CREATE TABLE IF NOT EXISTS database_service_providers -( - id VARCHAR(64) NOT NULL, - profile_id VARCHAR(64) NOT NULL, - service_provider_name VARCHAR(128) NULL, - created TIMESTAMP NOT NULL, - updated TIMESTAMP NOT NULL, - owner VARCHAR(128) NOT NULL, - enabled VARCHAR(16) NOT NULL DEFAULT 'enabled', - service_provider_metadata JSONB NOT NULL DEFAULT '{}', - configuration_references JSONB NOT NULL DEFAULT '{}', - attributes JSONB NOT NULL DEFAULT '{}', - - PRIMARY KEY (id, profile_id) -); - -COMMENT ON COLUMN database_service_providers.id IS 'The service provider ID of this service provider instance'; -COMMENT ON COLUMN database_service_providers.profile_id IS 'The profile ID owning this service provider instance'; -COMMENT ON COLUMN database_service_providers.service_provider_name IS 'The optional database service provider display name'; -COMMENT ON COLUMN database_service_providers.created IS 'When this service provider was originally created (in UTC time)'; -COMMENT ON COLUMN database_service_providers.updated IS 'When this service provider was last updated (in UTC time)'; -COMMENT ON COLUMN database_service_providers.owner IS 'The owner of the database service provider. This is the user or service provider who has administrative rights on the database service provider'; -COMMENT ON COLUMN database_service_providers.service_provider_metadata IS 'Metadata, as a JSON document, tied to this service provider, especially tags categorizing it'; -COMMENT ON COLUMN database_service_providers.configuration_references IS 'JSON document with all attributes referencing an item in the configuration'; -COMMENT ON COLUMN database_service_providers.attributes IS 'Canonical object representing this service provider'; - -CREATE INDEX IF NOT EXISTS IDX_DBSP_PROFILE_ID ON database_service_providers (profile_id); -CREATE INDEX IF NOT EXISTS IDX_DBSP_SERVICE_PROVIDER_NAME ON database_service_providers (service_provider_name); -CREATE INDEX IF NOT EXISTS IDX_DBSP_OWNER ON database_service_providers (owner); - -CREATE TABLE entities -( - id VARCHAR(64) NOT NULL PRIMARY KEY, - tenant_id VARCHAR(64) NULL, - context_id VARCHAR(64) NOT NULL, - type VARCHAR(64) NOT NULL, - value VARCHAR(512) NOT NULL, - display_name VARCHAR(255) NULL, - versions JSONB NOT NULL, - attributes JSONB NULL, - external_id VARCHAR(64) NULL, - created TIMESTAMP NOT NULL, - updated TIMESTAMP NOT NULL, - deleted TIMESTAMP NULL, - version VARCHAR(64) NOT NULL DEFAULT '1', - CONSTRAINT "FK_ENTITIES_CONTEXT_ID" FOREIGN KEY (context_id) REFERENCES entities (id) -); - -CREATE UNIQUE INDEX "IDX_ENTITIES_BUSINESS_KEY" ON entities (tenant_id, context_id, type, value); -CREATE UNIQUE INDEX "IDX_ENTITIES_BUSINESS_KEY_DEFAULT" ON entities (context_id, type, value) WHERE tenant_id IS NULL; -CREATE INDEX "IDX_ENTITIES_TENANT_TYPE_VALUE" ON entities (tenant_id, type, value); -CREATE INDEX "IDX_ENTITIES_TENANT_TYPE_VALUE_DEFAULT" ON entities (type, value) WHERE tenant_id IS NULL; -CREATE INDEX "IDX_ENTITIES_EXTERNAL_ID" ON entities (external_id); --- Postgres does not automatically create an index for foreign keys, the index must be created by hand for improved performance. -CREATE INDEX "IDX_ENTITIES_CONTEXT_ID" ON entities (context_id); - -COMMENT ON COLUMN entities.id IS 'Unique ID of the entity'; -COMMENT ON COLUMN entities.tenant_id IS 'The tenant ID of this entity'; -COMMENT ON COLUMN entities.context_id IS 'The entity ID of the context owning this entity'; -COMMENT ON COLUMN entities.type IS 'The type of the entity, e.g. a group'; -COMMENT ON COLUMN entities.value IS 'The value of the entity, e.g. developer'; -COMMENT ON COLUMN entities.display_name IS 'The display name of the entity'; -COMMENT ON COLUMN entities.versions IS 'A JSON object to manage resource relations associated with the entity'; -COMMENT ON COLUMN entities.attributes IS 'A JSON object of additional attributes associated with the entity'; -COMMENT ON COLUMN entities.external_id IS 'The external ID of the entity'; -COMMENT ON COLUMN entities.created IS 'When this entity was created'; -COMMENT ON COLUMN entities.updated IS 'When this entity was last updated'; -COMMENT ON COLUMN entities.deleted IS 'When this entity was deleted, NULL otherwise'; -COMMENT ON COLUMN entities.version IS 'The version of the entity'; - -INSERT INTO entities (id, tenant_id, context_id, type, value, display_name, versions, attributes, created, updated, version) -VALUES ('__GLOBAL__', '__ROOT__', '__GLOBAL__', '__SYSTEM__', '__GLOBAL__', 'Global context (e.g. for context entities)', '{}', '{}', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, '1'); - -CREATE TABLE entity_relations ( - id VARCHAR(64) NOT NULL PRIMARY KEY, - source_entity_id VARCHAR(64) NOT NULL, - target_entity_id VARCHAR(64) NOT NULL, - type VARCHAR(64) NOT NULL, - tenant_id VARCHAR(64) NULL, - created TIMESTAMP NOT NULL, - attributes JSONB NULL, - CONSTRAINT "FK_ENTITY_RELATIONS_SOURCE_ENTITY_ID" FOREIGN KEY (source_entity_id) REFERENCES entities (id), - CONSTRAINT "FK_ENTITY_RELATIONS_TARGET_ENTITY_ID" FOREIGN KEY (target_entity_id) REFERENCES entities (id) -); - --- These two indexes will be used to efficiently enforce the foreign keys. -CREATE UNIQUE INDEX "IDX_ENTITY_RELATIONS_BUSINESS_KEY" ON entity_relations (source_entity_id, type, target_entity_id); -CREATE UNIQUE INDEX "IDX_ENTITY_RELATIONS_REVERSE_BUSINESS_KEY" ON entity_relations (target_entity_id, type, source_entity_id); - -COMMENT ON COLUMN entity_relations.id IS 'Unique ID of the entity relation'; -COMMENT ON COLUMN entity_relations.source_entity_id IS 'ID of the source entity of the relation'; -COMMENT ON COLUMN entity_relations.target_entity_id IS 'ID of the target entity of the relation'; -COMMENT ON COLUMN entity_relations.type IS 'The relation type'; -COMMENT ON COLUMN entity_relations.tenant_id IS 'The tenant ID of this entity relation'; -COMMENT ON COLUMN entity_relations.created IS 'When this entity relation was created'; -COMMENT ON COLUMN entity_relations.attributes IS 'A JSON object of additional attributes associated with the entity relation'; - -CREATE TABLE account_resource_relations ( - id VARCHAR(64) NOT NULL PRIMARY KEY, - account_id VARCHAR(64) NOT NULL, - tenant_id VARCHAR(64) NULL, - entity_id VARCHAR(64) NOT NULL, - type VARCHAR(64) NOT NULL, - relation_version INTEGER NOT NULL, - status VARCHAR(16) NOT NULL DEFAULT 'ACTIVE', - not_before TIMESTAMP NULL, - expires TIMESTAMP NULL, - attributes JSONB NULL, - created TIMESTAMP NOT NULL, - updated TIMESTAMP NOT NULL, - version VARCHAR(64) NOT NULL DEFAULT '1', - CONSTRAINT "FK_ACCOUNT_RESOURCE_RELATIONS_ENTITIES_ENTITY_ID" FOREIGN KEY (entity_id) REFERENCES entities (id) -); - -CREATE UNIQUE INDEX "IDX_ACCOUNT_RESOURCE_RELATIONS_BUSINESS_KEY" ON account_resource_relations (tenant_id, account_id, entity_id, type, relation_version); -CREATE UNIQUE INDEX "IDX_ACCOUNT_RESOURCE_RELATIONS_BUSINESS_KEY_DEFAULT" ON account_resource_relations (account_id, entity_id, type, relation_version) WHERE tenant_id IS NULL; --- Postgres does not automatically create an index for foreign keys, the index must be created by hand for improved performance. -CREATE INDEX "IDX_ACCOUNT_RESOURCE_RELATIONS_ENTITY_ID_TYPE" ON account_resource_relations(entity_id, type); - -COMMENT ON COLUMN account_resource_relations.id IS 'Unique ID of the relation'; -COMMENT ON COLUMN account_resource_relations.account_id IS 'The account ID of the relation'; -COMMENT ON COLUMN account_resource_relations.tenant_id IS 'The tenant ID of this relation. Must match tenant_id of the account_id'; -COMMENT ON COLUMN account_resource_relations.entity_id IS 'The entity ID associated to the account'; -COMMENT ON COLUMN account_resource_relations.type IS 'The relation type'; -COMMENT ON COLUMN account_resource_relations.relation_version IS 'The relation version when this relation was created'; -COMMENT ON COLUMN account_resource_relations.status IS 'The status of the relation from {''ACTIVE'', ''REVOKED''}'; -COMMENT ON COLUMN account_resource_relations.not_before IS 'The moment before which the relation is not valid'; -COMMENT ON COLUMN account_resource_relations.expires IS 'The moment after which the relation is not valid'; -COMMENT ON COLUMN account_resource_relations.attributes IS 'A JSON object of additional attributes associated with the relation'; -COMMENT ON COLUMN account_resource_relations.created IS 'When this relation was created'; -COMMENT ON COLUMN account_resource_relations.updated IS 'When this relation was last updated'; -COMMENT ON COLUMN account_resource_relations.version IS 'The version of the relation'; - -CREATE TABLE database_client_resource_relations ( - id VARCHAR(64) NOT NULL PRIMARY KEY, - database_client_id VARCHAR(64) NOT NULL, - tenant_id VARCHAR(64) NULL, - entity_id VARCHAR(64) NOT NULL, - type VARCHAR(64) NOT NULL, - relation_version INTEGER NOT NULL, - status VARCHAR(16) NOT NULL DEFAULT 'ACTIVE', - not_before TIMESTAMP NULL, - expires TIMESTAMP NULL, - attributes JSONB NULL, - created TIMESTAMP NOT NULL, - updated TIMESTAMP NOT NULL, - version VARCHAR(64) NOT NULL DEFAULT '1', - CONSTRAINT "FK_DATABASE_CLIENT_RESOURCE_RELATIONS_ENTITIES_ID" FOREIGN KEY (entity_id) REFERENCES entities (id) -); - -CREATE UNIQUE INDEX "IDX_DATABASE_CLIENT_RESOURCE_RELATIONS_BUSINESS_KEY" ON database_client_resource_relations (tenant_id, database_client_id, entity_id, type, relation_version); -CREATE UNIQUE INDEX "IDX_DATABASE_CLIENT_RESOURCE_RELATIONS_BUSINESS_KEY_DEFAULT" ON database_client_resource_relations (database_client_id, entity_id, type, relation_version) WHERE tenant_id IS NULL; --- Postgres does not automatically create an index for foreign keys, the index must be created by hand for improved performance. -CREATE INDEX "IDX_DATABASE_CLIENT_RESOURCE_RELATIONS_ENTITY_ID_TYPE" ON database_client_resource_relations(entity_id, type); - -COMMENT ON COLUMN database_client_resource_relations.id IS 'Unique ID of the relation'; -COMMENT ON COLUMN database_client_resource_relations.database_client_id IS 'The database client ID of the relation'; -COMMENT ON COLUMN database_client_resource_relations.tenant_id IS 'The tenant ID of this relation. Must match tenant_id of the database_client_id'; -COMMENT ON COLUMN database_client_resource_relations.entity_id IS 'The entity ID associated to the database client'; -COMMENT ON COLUMN database_client_resource_relations.type IS 'The relation type'; -COMMENT ON COLUMN database_client_resource_relations.relation_version IS 'The relation version when this relation was created'; -COMMENT ON COLUMN database_client_resource_relations.status IS 'The status of the relation from {''ACTIVE'', ''REVOKED''}'; -COMMENT ON COLUMN database_client_resource_relations.not_before IS 'The moment before which the relation is not valid'; -COMMENT ON COLUMN database_client_resource_relations.expires IS 'The moment after which the relation is not valid'; -COMMENT ON COLUMN database_client_resource_relations.attributes IS 'A JSON object of additional attributes associated with the relation'; -COMMENT ON COLUMN database_client_resource_relations.created IS 'When this relation was created'; -COMMENT ON COLUMN database_client_resource_relations.updated IS 'When this relation was last updated'; -COMMENT ON COLUMN database_client_resource_relations.version IS 'The version of the relation'; - -/* - * Restore some backed up users for testing - */ -COPY accounts (account_id, username, email, phone, attributes, active, created, updated) FROM stdin; -59aa5d82-4191-4f79-ba92-3ecb5720a135 dana dana@demo.example 01111 {"name": {"givenName": "Dana", "familyName": "Demo"}, "emails": [{"value": "dana@demo.example", "primary": true}], "customerId": "2099", "region": "USA", "roles": [{"value": "customer", "primary": true}], "agreeToTerms": "on", "phoneNumbers": [{"value": "01111", "primary": true}], "urn:se:curity:scim:2.0:Devices": []} 1 1713884200 1713884200 -cdb976b0-08f9-4a10-8e31-5a5577697a61 kim kim@demo.example 02222 {"name": {"givenName": "Kim", "familyName": "Test"}, "emails": [{"value": "kim@demo.example", "primary": true}], "customerId": "7791", "region": "USA", "roles": [{"value": "admin", "primary": true}], "agreeToTerms": "on", "phoneNumbers": [{"value": "02222", "primary": true}], "urn:se:curity:scim:2.0:Devices": []} 1 1713884223 1713884223 -\. - -COPY credentials (id, subject, password, attributes, created, updated) FROM stdin; -6a273e20-6015-4243-8117-44379cadf582 dana $5$rounds=20000$Se4r2wzZVdc8Pd1s$5HMyJamk.Z7D8VuaV9kerY2ne3VDqf43XSZa6krRiFC {} 2025-03-14 14:53:30.623009 2025-03-14 14:53:30.623009 -79b6852c-8062-403b-b0a9-3b19d7175233 kim $5$rounds=20000$gpwr9WiEHG7RxeRC$IH.QDBDcRK6WfTIp.Yeg7pL7ePEvDMHSwBP.irx0ym/ {} 2025-03-14 14:53:30.623009 2025-03-14 14:53:30.623009 diff --git a/resources/authorizationserver/deploy-authorization-server.sh b/resources/authorizationserver/deploy-authorization-server.sh index 449c981..83a1e07 100755 --- a/resources/authorizationserver/deploy-authorization-server.sh +++ b/resources/authorizationserver/deploy-authorization-server.sh @@ -38,9 +38,21 @@ kubectl delete namespace authorizationserver 2>/dev/null kubectl create namespace authorizationserver # -# Deploy a Postgres database used by the authorization server +# Copy in the latest schema creation script from the Curity Docker image +# +docker pull curity.azurecr.io/curity/idsvr +docker run --name curity -d -e PASSWORD=Password1 curity.azurecr.io/curity/idsvr +docker cp curity:/opt/idsvr/etc/postgres-create_database.sql ./create-schema.sql +docker rm --force curity 1>/dev/null +if [ ! -f ./create-schema.sql ]; then + echo 'Problem encountered getting the schema creation script' + exit 1 +fi + +# +# Create a configmap with scripts, which PostgreSQL executes in an alphabetical sequence # -kubectl -n authorizationserver create configmap postgres-configmap --from-file='data-backup.sql' +kubectl -n authorizationserver create configmap postgres-configmap --from-file='create-schema.sql' --from-file='import-users.sql' if [ $? -ne 0 ]; then echo 'Problem encountered creating the postgres configmap' exit 1 diff --git a/resources/authorizationserver/import-users.sql b/resources/authorizationserver/import-users.sql new file mode 100644 index 0000000..db5ecb6 --- /dev/null +++ b/resources/authorizationserver/import-users.sql @@ -0,0 +1,12 @@ +/* + * Import some backed up test users + */ + +COPY accounts (account_id, username, email, phone, attributes, active, created, updated) FROM stdin; +59aa5d82-4191-4f79-ba92-3ecb5720a135 dana dana@demo.example 01111 {"name": {"givenName": "Dana", "familyName": "Demo"}, "emails": [{"value": "dana@demo.example", "primary": true}], "customerId": "2099", "region": "USA", "roles": [{"value": "customer", "primary": true}], "agreeToTerms": "on", "phoneNumbers": [{"value": "01111", "primary": true}], "urn:se:curity:scim:2.0:Devices": []} 1 1713884200 1713884200 +cdb976b0-08f9-4a10-8e31-5a5577697a61 kim kim@demo.example 02222 {"name": {"givenName": "Kim", "familyName": "Test"}, "emails": [{"value": "kim@demo.example", "primary": true}], "customerId": "7791", "region": "USA", "roles": [{"value": "admin", "primary": true}], "agreeToTerms": "on", "phoneNumbers": [{"value": "02222", "primary": true}], "urn:se:curity:scim:2.0:Devices": []} 1 1713884223 1713884223 +\. + +COPY credentials (id, subject, password, attributes, created, updated) FROM stdin; +6a273e20-6015-4243-8117-44379cadf582 dana $5$rounds=20000$Se4r2wzZVdc8Pd1s$5HMyJamk.Z7D8VuaV9kerY2ne3VDqf43XSZa6krRiFC {} 2025-03-14 14:53:30.623009 2025-03-14 14:53:30.623009 +79b6852c-8062-403b-b0a9-3b19d7175233 kim $5$rounds=20000$gpwr9WiEHG7RxeRC$IH.QDBDcRK6WfTIp.Yeg7pL7ePEvDMHSwBP.irx0ym/ {} 2025-03-14 14:53:30.623009 2025-03-14 14:53:30.623009 diff --git a/resources/authorizationserver/postgres.yaml b/resources/authorizationserver/postgres.yaml index 0b7220a..6c6c626 100644 --- a/resources/authorizationserver/postgres.yaml +++ b/resources/authorizationserver/postgres.yaml @@ -32,10 +32,10 @@ spec: spec: containers: - name: postgres - image: postgres:17.6 + image: postgres:18.4 volumeMounts: - mountPath: /docker-entrypoint-initdb.d - name: init-script + name: init-scripts readOnly: true env: - name: POSTGRES_USER @@ -48,6 +48,6 @@ spec: - containerPort: 5432 name: postgres volumes: - - name: init-script + - name: init-scripts configMap: name: postgres-configmap