#!/bin/sh set -eu : "${MYSQL_ACCESS_BROKER_USER:?MYSQL_ACCESS_BROKER_USER is required}" : "${MYSQL_ACCESS_BROKER_PASSWORD:?MYSQL_ACCESS_BROKER_PASSWORD is required}" : "${MYSQL_USER:?MYSQL_USER is required}" : "${MYSQL_PASSWORD:?MYSQL_PASSWORD is required}" if ! printf '%s' "${MYSQL_ACCESS_BROKER_USER}" | grep -Eq '^[A-Za-z][A-Za-z0-9_]{0,31}$'; then echo "MYSQL_ACCESS_BROKER_USER must be a safe MySQL account name" >&2 exit 1 fi if ! printf '%s' "${MYSQL_USER}" | grep -Eq '^[A-Za-z][A-Za-z0-9_]{0,31}$'; then echo "MYSQL_USER must be a safe MySQL account name" >&2 exit 1 fi if [ "${MYSQL_ACCESS_BROKER_USER}" = "root" ] || [ "${MYSQL_ACCESS_BROKER_USER}" = "${MYSQL_USER}" ]; then echo "MYSQL_ACCESS_BROKER_USER must be an isolated non-root account" >&2 exit 1 fi if [ "${MYSQL_ACCESS_BROKER_PASSWORD}" = "${MYSQL_PASSWORD}" ]; then echo "MYSQL_ACCESS_BROKER_PASSWORD must differ from MYSQL_PASSWORD" >&2 exit 1 fi if ! printf '%s' "${MYSQL_DATABASE}" | grep -Eq '^[A-Za-z][A-Za-z0-9_]{0,63}$'; then echo "MYSQL_DATABASE must be a safe MySQL database name" >&2 exit 1 fi if ! printf '%s' "${MYSQL_ACCESS_BROKER_PASSWORD}" | grep -Eq '^[A-Za-z0-9._~!@#%^+=:-]{24,128}$'; then echo "MYSQL_ACCESS_BROKER_PASSWORD must be 24-128 URL-safe characters" >&2 exit 1 fi # The database code is the physical MySQL database name, so project databases # do not share a technical prefix. Grant the non-administrative DDL/DML set # globally, then use MySQL partial revokes to exclude the mutable mysql schema # and sys views. information_schema and performance_schema are server-managed # read-only schemas, and the SQL console also blocks every system schema. The # dedicated platform_control database remains available to the service. mysql --protocol=socket -uroot -p"${MYSQL_ROOT_PASSWORD}" -e \ "GRANT CREATE, DROP, ALTER, INDEX, REFERENCES, SELECT, INSERT, UPDATE, DELETE, CREATE VIEW, SHOW VIEW, TRIGGER ON *.* TO '${MYSQL_USER}'@'%'; GRANT SYSTEM_USER ON *.* TO '${MYSQL_USER}'@'%'; REVOKE CREATE, DROP, ALTER, INDEX, REFERENCES, SELECT, INSERT, UPDATE, DELETE, CREATE VIEW, SHOW VIEW, TRIGGER ON \`mysql\`.* FROM '${MYSQL_USER}'@'%'; REVOKE CREATE, DROP, ALTER, INDEX, REFERENCES, SELECT, INSERT, UPDATE, DELETE, CREATE VIEW, SHOW VIEW, TRIGGER ON \`sys\`.* FROM '${MYSQL_USER}'@'%'; CREATE USER IF NOT EXISTS '${MYSQL_ACCESS_BROKER_USER}'@'%' IDENTIFIED BY '${MYSQL_ACCESS_BROKER_PASSWORD}'; ALTER USER '${MYSQL_ACCESS_BROKER_USER}'@'%' IDENTIFIED BY '${MYSQL_ACCESS_BROKER_PASSWORD}' PASSWORD EXPIRE NEVER FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME 1; GRANT SELECT, INSERT, UPDATE, DELETE, SHOW VIEW ON *.* TO '${MYSQL_ACCESS_BROKER_USER}'@'%' WITH GRANT OPTION; GRANT CREATE USER ON *.* TO '${MYSQL_ACCESS_BROKER_USER}'@'%'; REVOKE SELECT, INSERT, UPDATE, DELETE, SHOW VIEW ON \`${MYSQL_DATABASE}\`.* FROM '${MYSQL_ACCESS_BROKER_USER}'@'%'; REVOKE SELECT, INSERT, UPDATE, DELETE, SHOW VIEW ON \`mysql\`.* FROM '${MYSQL_ACCESS_BROKER_USER}'@'%'; REVOKE SELECT, INSERT, UPDATE, DELETE, SHOW VIEW ON \`performance_schema\`.* FROM '${MYSQL_ACCESS_BROKER_USER}'@'%'; REVOKE SELECT, INSERT, UPDATE, DELETE, SHOW VIEW ON \`sys\`.* FROM '${MYSQL_ACCESS_BROKER_USER}'@'%'; FLUSH PRIVILEGES;"