pkg/security no longer contains SQL. Every provider calls a store interface
from lookup, implemented by a procedure backend (Postgres stored procedures,
the default there) and a direct backend (dialect-driven SQL for postgres,
sqlite, mysql and mssql with configurable table and column names).
- add sectypes, lookup, lookup/{dialect,procedure,direct,backends,ddl,conformance}
- split totp and providers sub packages out of the core package
- replace SQLNames/TableNames/QueryMode with lookup.Config (see breaking_changes.md)
- direct backend now covers column/row security and API-key login
- move txsettings SQL to lookup.ApplyTxSettings; remove password.go
- move schema scripts under lookup/, add reference DDL per dialect
- add a shared conformance suite; run it on sqlite, and on Postgres in a
podman/docker container (RESOLVESPEC_TEST_CONTAINERS=1)
- fix procedure schema bugs found on real Postgres: duplicate p_data
parameter, JSON null arrays, expires_at timezone casts, passkey list
GROUP BY, missing resolvespec_passkey_login; accept zone-less timestamps
7.9 KiB
Breaking changes
Appended as each step of audit/sec_query_builder.plan.md lands.
Step 0: shared types moved to sectypes (no action needed)
The plain data types now live in pkg/security/sectypes and are aliased in pkg/security
(types.go), so security.UserContext and sectypes.UserContext are the same type.
Moved: UserContext, LoginRequest/Response, RegisterRequest, LogoutRequest,
PasswordReset*, KeyType (+ constants), UserKey, CreateKey*, OAuthServerClient,
OAuthCode, OAuthTokenInfo, Passkey* data structs, TwoFactorSecret, ColumnSecurity,
RowSecurity (incl. GetTemplate).
Step 0b (totp): moved to pkg/security/totp
Import github.com/bitechdev/ResolveSpec/pkg/security/totp. No aliases (import cycle).
| Old | New |
|---|---|
security.TwoFactorAuthProvider |
totp.AuthProvider |
security.TwoFactorConfig / DefaultTwoFactorConfig |
totp.Config / totp.DefaultConfig |
security.TOTPGenerator / NewTOTPGenerator |
totp.Generator / totp.NewGenerator |
security.GenerateBackupCodes |
totp.GenerateBackupCodes |
security.MemoryTwoFactorProvider / NewMemoryTwoFactorProvider |
totp.MemoryProvider / totp.NewMemoryProvider |
security.TwoFactorAuthenticator / NewTwoFactorAuthenticator |
totp.Authenticator / totp.NewAuthenticator |
totp.NewAuthenticator takes a totp.BaseAuthenticator (Login, Logout, Authenticate) instead of
security.Authenticator; any security.Authenticator satisfies it.
DatabaseTwoFactorProvider stays in security for now (it uses the core SQL internals) and moves
into totp once the lookup TOTPStore replaces them. Until then core imports totp, so totp
must not import security.
Step 0b (providers, first part): moved to pkg/security/providers
Import github.com/bitechdev/ResolveSpec/pkg/security/providers. Names unchanged, no aliases (import cycle).
| Old | New |
|---|---|
security.HeaderAuthenticator / NewHeaderAuthenticator |
providers.HeaderAuthenticator / providers.NewHeaderAuthenticator |
security.ConfigKeyStore / NewConfigKeyStore |
providers.ConfigKeyStore / providers.NewConfigKeyStore |
security.KeyStoreAuthenticator / NewKeyStoreAuthenticator |
providers.KeyStoreAuthenticator / providers.NewKeyStoreAuthenticator |
security.ConfigColumnSecurityProvider / NewConfigColumnSecurityProvider |
providers.ConfigColumnSecurityProvider / providers.NewConfigColumnSecurityProvider |
security.ConfigRowSecurityProvider / NewConfigRowSecurityProvider |
providers.ConfigRowSecurityProvider / providers.NewConfigRowSecurityProvider |
The SHA-256 key hash helper is now sectypes.HashKey. The database-backed providers
(DatabaseAuthenticator, JWTAuthenticator, DatabaseKeyStore, DatabaseColumn/RowSecurityProvider)
stay in security until the lookup stores replace their SQL.
Additions (no action needed)
common.SQLDBProvider(SQLDB() *sql.DB) is implemented by the bun, gorm and pgsql adapters (not their transaction adapters).lookup.FromDatabase(common.Database)uses it, plus the adapter'sDriverName(), to get the*sql.DBand dialect name.
Steps 2–3: lookup dialects and procedure backend
- New
lookup/dialect(postgres, sqlite, mysql, mssql) andlookup/procedurepackages. No existing exportedsecurityAPI changed in these steps. - Procedure-mode code paths in
DatabaseAuthenticator,JWTAuthenticator, the policy providers,DatabaseKeyStore,DatabaseTwoFactorProviderandDatabasePasskeyProvidernow delegate tolookup/procedure. Error texts are unchanged. - Behaviour change (improvement): these procedure paths now reconnect once on a closed
*sql.DB(JWT logout, key create, TOTP, passkey, OAuth previously used the handle directly).
Step 4: lookup/direct backend
- New
lookup/directpackage: table-backed stores for auth, keys, OAuth (client + user), passkey, TOTP and policy, built fromlookup.Schemaand the dialect. Nothing inpkg/securitycalls it yet (wiring is step 5), so no existing API changes here. - Direct
LoginAPIKeyis new:header_api/apikeys only; unknown, expired, inactive and wrong-type keys (and inactive users) all returnlookup.ErrInvalidAPIKey. - Policy tables (
sec_group_members,sec_column_rules,sec_row_rules) are required for the direct policy store;PolicyOptions.NoGroupsskips the membership table. - Direct behaviour that changes when step 5 switches over: login, register, refresh, API-key login,
password reset and passkey login now write in one transaction;
Keys.Createstores NULL (not the textnull) for empty scopes/meta; OAuth code exchange consumes the code atomically; a non-numeric row-security user reference is an error instead of loading no rules.
Step 5: pkg/security uses lookup
pkg/security no longer contains SQL (guarded by TestCoreContainsNoSQL). Every database call goes
through a lookup.Provider built by lookup/backends.New.
Removed (replaced by lookup.Config: Dialect, Mode, Overrides, Procs, Schema):
- Types and functions
SQLNames,DefaultSQLNames,MergeSQLNames,ValidateSQLNames,TableNames(+ Default/Merge/Validate),KeyStoreSQLNames,KeyStoreTableNames(+ same),QueryMode,ModeAuto/ModeProcedure/ModeDirect,ErrDirectModeUnsupported. - Options fields
SQLNames,TableNames,QueryModeonDatabaseAuthenticatorOptions,DatabaseKeyStoreOptions,DatabasePasskeyProviderOptions; replaced byLookup lookup.ConfigandLookupProvider *lookup.Provider. - Builders
WithQueryMode,WithTableNamesonJWTAuthenticator, the column/row providers andDatabaseTwoFactorProvider; replaced byWithLookup(cfg)andWithLookupProvider(p). - The variadic
names ...*SQLNamesargument ofNewJWTAuthenticator,NewDatabaseColumnSecurityProvider,NewDatabaseRowSecurityProviderandNewDatabaseTwoFactorProvider.
Behaviour changes:
- Default mode is per dialect: stored procedures on Postgres, direct SQL elsewhere.
ModeAuto(probepg_proconce per procedure) is now opt-in vialookup.ModeAuto; it used to be the default everywhere. Procedure mode on a non-Postgres dialect is a configuration error. - A bad lookup configuration no longer panics or is silently ignored: the component logs it and every call returns the error.
- Dialect is detected from the driver; if detection fails the postgres dialect is assumed.
- Column and row security now work in direct mode (tables
sec_group_members,sec_column_rules,sec_row_rules); they used to returnErrDirectModeUnsupported.WithNoGroupTables()skips the group membership table. LoginWithAPIKeyworks in direct mode;DatabaseAuthenticator.Logoutnow clears the session cache in every mode (direct mode used to skip it).Authenticatenow holds the session lookup in the configured backend only; the activity update no longer silently falls back to a direct write when the procedure is missing.- Direct-mode behaviour changes listed under step 4 take effect here.
Step 6: schemas and docs
- SQL files moved from
pkg/security/topkg/security/lookup/(database_schema.sql,keystore_schema.sql).database_schema_sqlite.sqlis superseded bylookup/ddl/sqlite.sql(now also includessec_group_members,sec_column_rules,sec_row_rules). - New
lookup/ddlpackage: embedded reference table schemas forpostgres,sqlite,mysql,mssql(ddl.SQL(dialect),ddl.Statements(dialect)).ddl/postgres.sqlis tables only and uses base64 / JSON text columns, so it cannot be combined with the procedure schema (database_schema.sql,bytea/text[]columns) on the same tables. security.ApplyTxSettingsis unchanged; its SQL moved tolookup.ApplyTxSettings(ctx, tx, settings).- Removed the unexported
password.gofrompkg/security(bcrypt helpers live inlookup/direct). README.md,KEYSTORE.mdand the root README describelookup.Configinstead ofQueryMode,SQLNamesandTableNames.