package database import "os" // THE ROLE NAMES THE BATCH JOBS ASSERT, resolved from the environment with the production names as defaults. // // WHY THIS EXISTS. Every batch command asserted a hard coded role name: "missionmatch_app" and friends. The // name is a typo guard, catching an operator who pastes the migrator DSN into a job that must not have // BYPASSRLS. It is NOT the security property, which is the rolbypassrls check inside AssertRole and which // runs regardless of what the name resolves to. // // The consequence of hard coding it was that NO BATCH JOB COULD RUN ON STAGING. Staging's application role is // missionmatch_staging_app, so alert-sweep, teach-aggregate, import-bench, demo-seed, tag-missions, // aioe-backfill and staffing-proactive-sync all refused at boot with a role mismatch. The entire scheduled // surface of this product was production only by construction, which means it could only ever be exercised // for the first time in production. The alert watch loop was found this way: a redeployment sweep on staging // refused before it read a single row. // // The default is the production name, so nothing changes for production and no environment file has to gain a // variable. Staging sets the variable and the jobs run there. func roleName(env, fallback string) string { if v := os.Getenv(env); v != "" { return v } return fallback } // AppRoleName is the NOBYPASSRLS application role every tenant scoped batch job must authenticate as. func AppRoleName() string { return roleName("MM_APP_DB_ROLE", "missionmatch_app") } // ComplianceRoleName is the role that reaches the walled off eeo schema. func ComplianceRoleName() string { return roleName("MM_COMPLIANCE_DB_ROLE", "missionmatch_compliance") } // AIOERoleName is the role the optimization engine authenticates as. func AIOERoleName() string { return roleName("MM_AIOE_DB_ROLE", "missionmatch_aioe") }