@rehearsal-db/core 0.1.0-beta.9 → 0.1.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +319 -1
- package/COMPATIBILITY.md +15 -0
- package/README.md +73 -16
- package/dist/package.json +100 -0
- package/dist/scripts/install/create_root_config.d.mts +3 -0
- package/dist/scripts/install/create_root_config.mjs +13 -0
- package/dist/scripts/runtime/manage_database.d.mts +6 -0
- package/{scripts → dist/scripts}/runtime/manage_database.mjs +6 -8
- package/dist/src/application/interactive_task.d.mts +30 -0
- package/dist/src/application/interactive_task.mjs +83 -0
- package/dist/src/application/session.d.mts +97 -0
- package/dist/src/application/session.mjs +380 -0
- package/dist/src/baseline/artifact.d.mts +119 -0
- package/dist/src/baseline/artifact.mjs +522 -0
- package/dist/src/baseline/builder.d.mts +19 -0
- package/dist/src/baseline/builder.mjs +142 -0
- package/dist/src/baseline/input_discovery.d.mts +13 -0
- package/dist/src/baseline/input_discovery.mjs +149 -0
- package/dist/src/baseline/policy_review.d.mts +56 -0
- package/dist/src/baseline/policy_review.mjs +73 -0
- package/dist/src/baseline/preparation.d.mts +63 -0
- package/dist/src/baseline/preparation.mjs +295 -0
- package/dist/src/baseline/privacy_contract.d.mts +147 -0
- package/dist/src/baseline/privacy_contract.mjs +2 -0
- package/dist/src/baseline/privacy_dependency_graph.d.mts +7 -0
- package/dist/src/baseline/privacy_dependency_graph.mjs +110 -0
- package/dist/src/baseline/privacy_engine.d.mts +5 -0
- package/dist/src/baseline/privacy_engine.mjs +4 -0
- package/dist/src/baseline/privacy_key.d.mts +7 -0
- package/dist/src/baseline/privacy_key.mjs +42 -0
- package/dist/src/baseline/privacy_pipeline.d.mts +7 -0
- package/dist/src/baseline/privacy_pipeline.mjs +127 -0
- package/dist/src/baseline/privacy_policy.d.mts +6 -0
- package/dist/src/baseline/privacy_policy.mjs +237 -0
- package/dist/src/baseline/privacy_recipe_validation.d.mts +5 -0
- package/dist/src/baseline/privacy_recipe_validation.mjs +289 -0
- package/dist/src/baseline/privacy_rule_registry.d.mts +18 -0
- package/dist/src/baseline/privacy_rule_registry.mjs +143 -0
- package/dist/src/baseline/privacy_structured_json.d.mts +66 -0
- package/dist/src/baseline/privacy_structured_json.mjs +464 -0
- package/dist/src/baseline/privacy_transforms.d.mts +18 -0
- package/dist/src/baseline/privacy_transforms.mjs +142 -0
- package/dist/src/baseline/privacy_validation_shared.d.mts +31 -0
- package/dist/src/baseline/privacy_validation_shared.mjs +127 -0
- package/dist/src/baseline/sanitization_policy.d.mts +69 -0
- package/dist/src/baseline/sanitization_policy.mjs +227 -0
- package/dist/src/baseline/schema_snapshot.d.mts +19 -0
- package/dist/src/baseline/schema_snapshot.mjs +79 -0
- package/dist/src/cli/application_command_handlers.d.mts +8 -0
- package/dist/src/cli/application_command_handlers.mjs +52 -0
- package/dist/src/cli/arguments.d.mts +38 -0
- package/dist/src/cli/arguments.mjs +130 -0
- package/dist/src/cli/basic_command_handlers.d.mts +4 -0
- package/dist/src/cli/basic_command_handlers.mjs +57 -0
- package/dist/src/cli/cli_commands.d.mts +14 -0
- package/dist/src/cli/cli_commands.mjs +34 -0
- package/dist/src/cli/command_contract.d.mts +57 -0
- package/dist/src/cli/command_contract.mjs +39 -0
- package/dist/src/cli/command_output.d.mts +12 -0
- package/dist/src/cli/command_output.mjs +20 -0
- package/dist/src/cli/command_registry.d.mts +7 -0
- package/dist/src/cli/command_registry.mjs +14 -0
- package/dist/src/cli/guided.d.mts +53 -0
- package/dist/src/cli/guided.mjs +727 -0
- package/dist/src/cli/identity_command_handlers.d.mts +12 -0
- package/dist/src/cli/identity_command_handlers.mjs +239 -0
- package/dist/src/cli/identity_renderer.d.mts +8 -0
- package/dist/src/cli/identity_renderer.mjs +33 -0
- package/dist/src/cli/init_command.d.mts +21 -0
- package/dist/src/cli/init_command.mjs +90 -0
- package/dist/src/cli/inspection_command_handlers.d.mts +3 -0
- package/dist/src/cli/inspection_command_handlers.mjs +79 -0
- package/dist/src/cli/project_command_handlers.d.mts +11 -0
- package/dist/src/cli/project_command_handlers.mjs +92 -0
- package/dist/src/cli/project_commands.d.mts +283 -0
- package/dist/src/cli/project_commands.mjs +192 -0
- package/dist/src/cli/rehearsal.d.mts +7 -0
- package/dist/src/cli/rehearsal.mjs +190 -0
- package/dist/src/cli/renderers.d.mts +299 -0
- package/dist/src/cli/renderers.mjs +554 -0
- package/dist/src/cli/runtime_action_handlers.d.mts +12 -0
- package/dist/src/cli/runtime_action_handlers.mjs +201 -0
- package/dist/src/cli/runtime_commands.d.mts +294 -0
- package/dist/src/cli/runtime_commands.mjs +619 -0
- package/dist/src/cli/source_command_handlers.d.mts +8 -0
- package/dist/src/cli/source_command_handlers.mjs +62 -0
- package/dist/src/cli/source_commands.d.mts +436 -0
- package/dist/src/cli/source_commands.mjs +301 -0
- package/dist/src/cli/terminal.d.mts +59 -0
- package/dist/src/cli/terminal.mjs +230 -0
- package/dist/src/identity/claim.d.mts +5 -0
- package/dist/src/identity/claim.mjs +4 -0
- package/dist/src/identity/claim_contract.d.mts +135 -0
- package/dist/src/identity/claim_contract.mjs +6 -0
- package/dist/src/identity/claim_executor.d.mts +10 -0
- package/dist/src/identity/claim_executor.mjs +358 -0
- package/dist/src/identity/claim_identity_lookup.d.mts +23 -0
- package/dist/src/identity/claim_identity_lookup.mjs +134 -0
- package/dist/src/identity/claim_plan.d.mts +8 -0
- package/dist/src/identity/claim_plan.mjs +61 -0
- package/dist/src/identity/claim_policy.d.mts +3 -0
- package/dist/src/identity/claim_policy.mjs +377 -0
- package/dist/src/identity/claim_sql.d.mts +10 -0
- package/dist/src/identity/claim_sql.mjs +46 -0
- package/dist/src/identity/claim_verification.d.mts +13 -0
- package/dist/src/identity/claim_verification.mjs +35 -0
- package/dist/src/identity/connect.d.mts +30 -0
- package/dist/src/identity/connect.mjs +111 -0
- package/dist/src/identity/provider_configuration.d.mts +37 -0
- package/dist/src/identity/provider_configuration.mjs +132 -0
- package/dist/src/identity/storage.d.mts +21 -0
- package/dist/src/identity/storage.mjs +122 -0
- package/dist/src/index.d.mts +4 -0
- package/dist/src/index.mjs +3 -0
- package/dist/src/project/configuration.d.mts +13 -0
- package/dist/src/project/configuration.mjs +9 -0
- package/dist/src/project/configuration_contract.d.mts +125 -0
- package/dist/src/project/configuration_contract.mjs +27 -0
- package/dist/src/project/configuration_discovery.d.mts +7 -0
- package/dist/src/project/configuration_discovery.mjs +37 -0
- package/dist/src/project/configuration_normalization.d.mts +107 -0
- package/dist/src/project/configuration_normalization.mjs +302 -0
- package/dist/src/project/configuration_rendering.d.mts +14 -0
- package/dist/src/project/configuration_rendering.mjs +228 -0
- package/dist/src/project/configuration_resolution.d.mts +125 -0
- package/dist/src/project/configuration_resolution.mjs +81 -0
- package/dist/src/project/configuration_schema.d.mts +22 -0
- package/dist/src/project/configuration_schema.mjs +160 -0
- package/dist/src/project/configuration_validation.d.mts +22 -0
- package/dist/src/project/configuration_validation.mjs +136 -0
- package/dist/src/project/install_scaffold.d.mts +42 -0
- package/dist/src/project/install_scaffold.mjs +263 -0
- package/dist/src/project/project_detection.d.mts +14 -0
- package/dist/src/project/project_detection.mjs +47 -0
- package/dist/src/project/setup.d.mts +87 -0
- package/dist/src/project/setup.mjs +414 -0
- package/dist/src/project/support_report.d.mts +88 -0
- package/dist/src/project/support_report.mjs +83 -0
- package/dist/src/runtime/cleanup.d.mts +85 -0
- package/dist/src/runtime/cleanup.mjs +311 -0
- package/dist/src/runtime/lifecycle_engine.d.mts +63 -0
- package/dist/src/runtime/lifecycle_engine.mjs +114 -0
- package/dist/src/runtime/migration_history.d.mts +51 -0
- package/dist/src/runtime/migration_history.mjs +170 -0
- package/dist/src/runtime/plan.d.mts +134 -0
- package/dist/src/runtime/plan.mjs +640 -0
- package/dist/src/runtime/policy.d.mts +66 -0
- package/dist/src/runtime/policy.mjs +369 -0
- package/dist/src/runtime/restore.d.mts +22 -0
- package/dist/src/runtime/restore.mjs +276 -0
- package/dist/src/runtime/service_environment.d.mts +11 -0
- package/dist/src/runtime/service_environment.mjs +58 -0
- package/dist/src/runtime/topology.d.mts +51 -0
- package/dist/src/runtime/topology.mjs +128 -0
- package/dist/src/shared/diagnostics.d.mts +97 -0
- package/dist/src/shared/diagnostics.mjs +170 -0
- package/dist/src/shared/human_output.d.mts +2 -0
- package/{src → dist/src}/shared/human_output.mjs +1 -3
- package/dist/src/shared/node_runtime.d.mts +14 -0
- package/dist/src/shared/node_runtime.mjs +25 -0
- package/dist/src/shared/operation_guard.d.mts +22 -0
- package/dist/src/shared/operation_guard.mjs +150 -0
- package/dist/src/shared/process_environment.d.mts +15 -0
- package/dist/src/shared/process_environment.mjs +50 -0
- package/dist/src/source/access.d.mts +165 -0
- package/dist/src/source/access.mjs +602 -0
- package/dist/src/source/asset_transfer.d.mts +27 -0
- package/dist/src/source/asset_transfer.mjs +202 -0
- package/dist/src/source/baseline.d.mts +66 -0
- package/dist/src/source/baseline.mjs +372 -0
- package/dist/src/source/external_reader.d.mts +42 -0
- package/dist/src/source/external_reader.mjs +278 -0
- package/dist/src/source/postgresql_access.d.mts +86 -0
- package/dist/src/source/postgresql_access.mjs +454 -0
- package/dist/src/source/privacy_paths.d.mts +10 -0
- package/dist/src/source/privacy_paths.mjs +27 -0
- package/dist/src/targets/driver.d.mts +2 -0
- package/dist/src/targets/driver.mjs +13 -0
- package/dist/src/targets/postgresql.d.mts +5 -0
- package/dist/src/targets/postgresql.mjs +620 -0
- package/dist/src/targets/supabase.d.mts +8 -0
- package/dist/src/targets/supabase.mjs +629 -0
- package/dist/src/targets/supabase_environment.d.mts +54 -0
- package/dist/src/targets/supabase_environment.mjs +184 -0
- package/dist/src/targets/target.d.mts +33 -0
- package/dist/src/targets/target.mjs +39 -0
- package/docs/README.md +35 -16
- package/docs/architecture.md +135 -10
- package/docs/commands.md +53 -15
- package/docs/configuration.md +186 -31
- package/docs/getting-started.md +66 -9
- package/docs/index.md +67 -0
- package/docs/production-source.md +175 -17
- package/docs/releasing.md +24 -12
- package/docs/roadmap.md +3 -2
- package/docs/runtime-lifecycle.md +99 -0
- package/docs/runtime-policies.md +80 -7
- package/docs/sanitization.md +572 -4
- package/docs/security-model.md +8 -0
- package/docs/stability.md +70 -0
- package/docs/standalone-workflow.md +36 -13
- package/docs/troubleshooting.md +82 -10
- package/docs/tutorial.md +7 -1
- package/docs/typescript.md +134 -0
- package/package.json +44 -29
- package/types/configuration.d.mts +5 -0
- package/src/README.md +0 -17
- package/src/application/session.mjs +0 -313
- package/src/baseline/artifact.mjs +0 -661
- package/src/baseline/builder.mjs +0 -164
- package/src/baseline/input_discovery.mjs +0 -155
- package/src/baseline/policy_review.mjs +0 -92
- package/src/baseline/preparation.mjs +0 -323
- package/src/baseline/privacy_engine.mjs +0 -413
- package/src/baseline/sanitization_policy.mjs +0 -299
- package/src/baseline/schema_snapshot.mjs +0 -113
- package/src/cli/arguments.mjs +0 -120
- package/src/cli/guided.mjs +0 -807
- package/src/cli/rehearsal.mjs +0 -933
- package/src/cli/renderers.mjs +0 -584
- package/src/cli/runtime_commands.mjs +0 -553
- package/src/cli/source_commands.mjs +0 -326
- package/src/cli/terminal.mjs +0 -275
- package/src/identity/claim.mjs +0 -975
- package/src/identity/storage.mjs +0 -165
- package/src/project/configuration.d.mts +0 -153
- package/src/project/configuration.mjs +0 -1197
- package/src/project/setup.mjs +0 -379
- package/src/project/support_report.mjs +0 -105
- package/src/runtime/cleanup.mjs +0 -381
- package/src/runtime/migration_history.mjs +0 -220
- package/src/runtime/plan.mjs +0 -685
- package/src/runtime/policy.mjs +0 -438
- package/src/runtime/restore.mjs +0 -329
- package/src/runtime/service_environment.mjs +0 -82
- package/src/runtime/topology.mjs +0 -177
- package/src/shared/diagnostics.mjs +0 -199
- package/src/shared/operation_guard.mjs +0 -162
- package/src/shared/process_environment.mjs +0 -68
- package/src/source/access.mjs +0 -578
- package/src/source/asset_transfer.mjs +0 -177
- package/src/source/baseline.mjs +0 -446
- package/src/source/postgresql_access.mjs +0 -480
- package/src/targets/postgresql.mjs +0 -808
- package/src/targets/supabase.mjs +0 -830
- package/src/targets/supabase_environment.mjs +0 -229
- package/src/targets/target.mjs +0 -66
|
@@ -23,6 +23,15 @@ The privacy key stays ignored under `.rehearsal`. The policy is safe to review i
|
|
|
23
23
|
control because it contains hashes and environment-variable names, not credentials,
|
|
24
24
|
URLs, or raw owner identifiers.
|
|
25
25
|
|
|
26
|
+
`credentialFile` must be inside the selected target's
|
|
27
|
+
`baseline.artifactDirectory`, under its `secrets` folder. With the default artifact
|
|
28
|
+
directory, use `.rehearsal/secrets/source-reader.env`. For a target whose artifact
|
|
29
|
+
directory is `targets/primary/.rehearsal`, use
|
|
30
|
+
`targets/primary/.rehearsal/secrets/source-reader.env` and place `privacyKey` there as
|
|
31
|
+
well. Rehearsal stores that target's access receipt beside its baseline at
|
|
32
|
+
`targets/primary/.rehearsal/source-access-receipt.json`; separate targets never share
|
|
33
|
+
the receipt or credential.
|
|
34
|
+
|
|
26
35
|
## 2. Declare the source boundary
|
|
27
36
|
|
|
28
37
|
`source-access-policy.json` uses this shape:
|
|
@@ -33,6 +42,7 @@ URLs, or raw owner identifiers.
|
|
|
33
42
|
"targetFingerprint": "<sha256 of the approved PostgreSQL host, port, and database>",
|
|
34
43
|
"administratorEnvironmentVariable": "REHEARSAL_SOURCE_ADMIN_URL",
|
|
35
44
|
"reader": {
|
|
45
|
+
"mode": "managed",
|
|
36
46
|
"role": "rehearsal_example_reader",
|
|
37
47
|
"ownerRole": "rehearsal_example_owner",
|
|
38
48
|
"credentialFile": ".rehearsal/secrets/source-reader.env",
|
|
@@ -61,7 +71,7 @@ URLs, or raw owner identifiers.
|
|
|
61
71
|
"view": "approved_owner_profile",
|
|
62
72
|
"targetSchema": "app_api",
|
|
63
73
|
"targetTable": "profiles",
|
|
64
|
-
"columns": ["id", "email"],
|
|
74
|
+
"columns": ["id", "email", "avatar_path"],
|
|
65
75
|
"orderBy": ["id"],
|
|
66
76
|
"rowScope": {
|
|
67
77
|
"kind": "approved-owner",
|
|
@@ -70,10 +80,28 @@ URLs, or raw owner identifiers.
|
|
|
70
80
|
}
|
|
71
81
|
}
|
|
72
82
|
],
|
|
73
|
-
"
|
|
83
|
+
"assetReader": {
|
|
84
|
+
"endpointFingerprint": "<sha256 of the approved Storage endpoint>",
|
|
85
|
+
"baseUrlEnvironmentVariable": "REHEARSAL_SOURCE_STORAGE_URL",
|
|
86
|
+
"tokenEnvironmentVariable": "REHEARSAL_SOURCE_STORAGE_TOKEN",
|
|
87
|
+
"maximumObjects": 1000,
|
|
88
|
+
"maximumObjectBytes": 52428800,
|
|
89
|
+
"maximumTotalBytes": 2147483648
|
|
90
|
+
},
|
|
91
|
+
"assets": [
|
|
92
|
+
{
|
|
93
|
+
"bucket": "avatars",
|
|
94
|
+
"prefixEnvironmentVariable": "REHEARSAL_APPROVED_OWNER_ID",
|
|
95
|
+
"rights": "approved-owner",
|
|
96
|
+
"pathMapping": "owner-storage"
|
|
97
|
+
}
|
|
98
|
+
]
|
|
74
99
|
}
|
|
75
100
|
```
|
|
76
101
|
|
|
102
|
+
`managed` is the default for existing policies, but writing it explicitly makes the
|
|
103
|
+
credential boundary easier to review.
|
|
104
|
+
|
|
77
105
|
Calculate fingerprints with the exported helpers from `@rehearsal-db/core/source-access`
|
|
78
106
|
or a reviewed local script. A fingerprint binds the destination without recording its
|
|
79
107
|
address. Changing the host, port, or database invalidates the plan.
|
|
@@ -82,13 +110,92 @@ address. Changing the host, port, or database invalidates the plan.
|
|
|
82
110
|
use. `approved-owner` requires one explicit owner value from the named environment
|
|
83
111
|
variable. Rehearsal never chooses an owner by finding an administrator.
|
|
84
112
|
|
|
113
|
+
### Use a provider-managed reader
|
|
114
|
+
|
|
115
|
+
If a database owner already supplies the restricted export views and reader, use
|
|
116
|
+
`mode: "external"`. Omit `administratorEnvironmentVariable`; Rehearsal will not request
|
|
117
|
+
an administrator credential or change the source:
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"reader": {
|
|
122
|
+
"mode": "external",
|
|
123
|
+
"role": "provided_rehearsal_reader",
|
|
124
|
+
"allowedMemberships": ["provided_rehearsal_readers"],
|
|
125
|
+
"connectionEnvironmentVariable": "REHEARSAL_SOURCE_READER_URL",
|
|
126
|
+
"credentialFile": ".rehearsal/secrets/source-reader.env",
|
|
127
|
+
"maximumValidForMinutes": 30
|
|
128
|
+
},
|
|
129
|
+
"exportSchema": "provided_rehearsal_export",
|
|
130
|
+
"relations": [
|
|
131
|
+
{
|
|
132
|
+
"source": { "schema": "private", "table": "profiles" },
|
|
133
|
+
"view": "approved_owner_profile",
|
|
134
|
+
"targetSchema": "app_api",
|
|
135
|
+
"targetTable": "profiles",
|
|
136
|
+
"columns": ["id", "email", "avatar_path"],
|
|
137
|
+
"orderBy": ["id"],
|
|
138
|
+
"rowScope": {
|
|
139
|
+
"kind": "approved-owner",
|
|
140
|
+
"column": "id",
|
|
141
|
+
"valueEnvironmentVariable": "REHEARSAL_APPROVED_OWNER_ID"
|
|
142
|
+
},
|
|
143
|
+
"viewDefinitionSha256": "<sha256 from externalViewDefinitionFingerprint>"
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
The database owner must create a `security_barrier` view owned by a role other than the
|
|
150
|
+
reader. Record PostgreSQL's exact canonical definition, not handwritten SQL:
|
|
151
|
+
|
|
152
|
+
```js
|
|
153
|
+
import { externalViewDefinitionFingerprint } from "@rehearsal-db/core/source-access";
|
|
154
|
+
|
|
155
|
+
console.log(externalViewDefinitionFingerprint(canonicalViewDefinition));
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Obtain `canonicalViewDefinition` with
|
|
159
|
+
`select pg_get_viewdef('provided_rehearsal_export.approved_owner_profile'::regclass, false)`.
|
|
160
|
+
Rehearsal verifies that fingerprint before saving any local access receipt.
|
|
161
|
+
The resulting receipt also binds the normalized source-policy fingerprint. Editing the
|
|
162
|
+
view hash, columns, scopes, or reader declaration requires a new verification.
|
|
163
|
+
|
|
164
|
+
External mode also requires all non-system readable columns to match only the declared
|
|
165
|
+
views and migration-ledger columns. It refuses database, schema, relation, or column
|
|
166
|
+
writes; privileged role attributes; executable non-system security-definer functions;
|
|
167
|
+
a reader-owned view; or a database-enforced expiration beyond
|
|
168
|
+
`maximumValidForMinutes`.
|
|
169
|
+
|
|
170
|
+
This audit is intentionally conservative: an object-level table, column, sequence, or
|
|
171
|
+
function grant remains disallowed even when its schema currently lacks `USAGE`. Do not
|
|
172
|
+
use schema visibility to hide stale grants. Revoke the object grant or move the approved
|
|
173
|
+
surface behind the reviewed export views; this also avoids relying on behavior of an
|
|
174
|
+
already-open or prepared database session.
|
|
175
|
+
|
|
176
|
+
An external login may inherit its narrow permissions from provider-owned group roles.
|
|
177
|
+
List every direct group in `allowedMemberships`; omit the field or use `[]` when the
|
|
178
|
+
login has direct grants only. Rehearsal requires the observed membership set to match
|
|
179
|
+
that list exactly. Every allowed group must be non-login and non-privileged, grant
|
|
180
|
+
inheritance to the login, disable both `SET ROLE` and membership delegation, inherit no
|
|
181
|
+
other role, and own none of the export views. PostgreSQL versions that cannot prove the
|
|
182
|
+
per-membership role-switch setting are refused. Rehearsal still evaluates the login's
|
|
183
|
+
complete effective read, write, sequence, and executable-function surface after those
|
|
184
|
+
checks. Adding, removing, or changing a group changes the reviewed plan digest.
|
|
185
|
+
|
|
85
186
|
`targetSchema` is optional and defaults to `public`. Set it when the restored relation
|
|
86
187
|
belongs elsewhere, and use the same schema in privacy policy version 2. This is relation
|
|
87
188
|
identity, not a request to search every schema.
|
|
88
189
|
|
|
89
|
-
For Storage,
|
|
90
|
-
|
|
91
|
-
|
|
190
|
+
For Storage, the reader URL and token come from named environment variables. A public,
|
|
191
|
+
non-identity prefix may use `prefix`. A private owner prefix uses
|
|
192
|
+
`prefixEnvironmentVariable`, `rights: "approved-owner"`, and a `pathMapping` declared in
|
|
193
|
+
the privacy policy below. Its raw value stays out of tracked files and the review plan
|
|
194
|
+
records only its SHA-256. Objects outside the exact bucket/prefix are not listed or
|
|
195
|
+
downloaded. Size, object-count, path, ETag, and exact-byte checks apply.
|
|
196
|
+
Supabase folder entries are traversed recursively beneath that exact prefix. Folder
|
|
197
|
+
entries count toward `maximumObjects`, so the same reviewed limit bounds both the
|
|
198
|
+
directory walk and transferred files. Empty files remain files and are copied normally.
|
|
92
199
|
|
|
93
200
|
## 3. Use executable privacy policy version 2
|
|
94
201
|
|
|
@@ -98,6 +205,21 @@ Every selected column has one action and, where required, a bounded recipe:
|
|
|
98
205
|
{
|
|
99
206
|
"policyVersion": 2,
|
|
100
207
|
"migrationCutoff": "20260101000000",
|
|
208
|
+
"bindings": {
|
|
209
|
+
"approved-owner": {
|
|
210
|
+
"environmentVariable": "REHEARSAL_APPROVED_OWNER_ID",
|
|
211
|
+
"approvedValueSha256": "<sha256 of the exact approved owner ID>"
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
"pathMappings": {
|
|
215
|
+
"owner-storage": {
|
|
216
|
+
"binding": "approved-owner",
|
|
217
|
+
"format": "uuid",
|
|
218
|
+
"namespace": "account-id",
|
|
219
|
+
"maximumBytes": 512,
|
|
220
|
+
"maximumSegments": 8
|
|
221
|
+
}
|
|
222
|
+
},
|
|
101
223
|
"tables": [
|
|
102
224
|
{
|
|
103
225
|
"schema": "app_api",
|
|
@@ -119,6 +241,14 @@ Every selected column has one action and, where required, a bounded recipe:
|
|
|
119
241
|
"generated": "NEVER",
|
|
120
242
|
"identity": "NO",
|
|
121
243
|
"foreignKey": null
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
"name": "avatar_path",
|
|
247
|
+
"action": "DERIVE",
|
|
248
|
+
"recipe": { "kind": "path-map", "mapping": "owner-storage" },
|
|
249
|
+
"generated": "NEVER",
|
|
250
|
+
"identity": "NO",
|
|
251
|
+
"foreignKey": null
|
|
122
252
|
}
|
|
123
253
|
]
|
|
124
254
|
}
|
|
@@ -126,10 +256,13 @@ Every selected column has one action and, where required, a bounded recipe:
|
|
|
126
256
|
}
|
|
127
257
|
```
|
|
128
258
|
|
|
129
|
-
Supported recipes are intentionally small: keyed UUID/email/text/integer
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
259
|
+
Supported recipes are intentionally small: keyed UUID/email/text/integer/hex/GTIN/URL
|
|
260
|
+
pseudonyms, hexadecimal digests of explicitly named sanitized columns, explicit
|
|
261
|
+
constants, bounded or grouped date shifts, identity-aware path mappings, bounded
|
|
262
|
+
reviewed-identity substitution inside retained text, and fully classified JSON
|
|
263
|
+
structures. Unknown tables, columns, digest inputs, JSON keys, formats, and recipes stop
|
|
264
|
+
the refresh. There is no JavaScript or SQL escape hatch. See
|
|
265
|
+
[Sanitization policy](sanitization.md) for complete path and date examples.
|
|
133
266
|
|
|
134
267
|
## 4. Preview, apply, refresh, and retire
|
|
135
268
|
|
|
@@ -146,10 +279,12 @@ npx rehearsal source retire
|
|
|
146
279
|
npx rehearsal source retire --confirm-source-retirement=<full-sha256>
|
|
147
280
|
```
|
|
148
281
|
|
|
149
|
-
`source apply` creates new time-limited roles and export views only when
|
|
150
|
-
is unused. It verifies the reader cannot read raw tables, write,
|
|
151
|
-
an exposed security-definer network function.
|
|
152
|
-
|
|
282
|
+
In managed mode, `source apply` creates new time-limited roles and export views only when
|
|
283
|
+
every exact name is unused. It verifies the reader cannot read raw tables, write,
|
|
284
|
+
escalate roles, or call an exposed security-definer network function. In external mode,
|
|
285
|
+
the same command performs only the read-only checks above and stores the already supplied
|
|
286
|
+
credential in the ignored owner-only local file. It never creates, grants, alters, or
|
|
287
|
+
drops a source object.
|
|
153
288
|
|
|
154
289
|
`refresh` previews the complete replacement first. After exact confirmation, its baseline
|
|
155
290
|
step uses one read-only repeatable-read transaction for the schema shape,
|
|
@@ -160,13 +295,36 @@ runtime is rolled back to the previous baseline and runtime. The lower-level `ba
|
|
|
160
295
|
refresh` command remains available when automation should activate a baseline without
|
|
161
296
|
resetting the runtime or pruning old generations.
|
|
162
297
|
|
|
298
|
+
Rows committed after the repeatable-read transaction begins belong to the next refresh;
|
|
299
|
+
they cannot leak into the current snapshot midway through streaming. A schema or ledger
|
|
300
|
+
change during preparation stops activation. Malformed batches, network loss, interruption,
|
|
301
|
+
limit overruns, and low disk also leave the previous baseline active. Because `baseline
|
|
302
|
+
refresh` never resets the runtime, local runtime edits remain in place whether that
|
|
303
|
+
baseline-only preparation succeeds or fails.
|
|
304
|
+
|
|
305
|
+
Privacy `identity` metadata describes PostgreSQL `GENERATED ... AS IDENTITY`, not a
|
|
306
|
+
person or account identifier. UUID account keys normally use `identity: "NO"` while
|
|
307
|
+
remaining explicitly pseudonymized. During restore, Rehearsal consults the actual local
|
|
308
|
+
table for a backing sequence before resetting it; UUID columns never receive numeric
|
|
309
|
+
`max` or `setval` operations.
|
|
310
|
+
|
|
163
311
|
Storage cannot share PostgreSQL's transaction snapshot. Rehearsal instead verifies each
|
|
164
312
|
object's inventory version and byte count during transfer, then records its SHA-256 in
|
|
165
|
-
the immutable baseline.
|
|
313
|
+
the immutable baseline. For an identity-aware path, the database reference and physical
|
|
314
|
+
destination use the same package-owned pseudonym; the source suffix is preserved.
|
|
315
|
+
|
|
316
|
+
In managed mode, `source retire` inventories the exact recorded views before removal,
|
|
317
|
+
then removes only those views, the two recorded roles, and local credential/receipt
|
|
318
|
+
files. In external mode, it removes only Rehearsal's local credential and receipt; the
|
|
319
|
+
provider-owned role and views remain untouched. The database-enforced expiration still
|
|
320
|
+
limits access, and the provider may revoke it sooner. Rehearsal does not claim that local
|
|
321
|
+
cleanup revoked a provider-owned credential. Unrelated roles, grants, objects, baselines,
|
|
322
|
+
runtimes, and Docker resources are preserved.
|
|
166
323
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
324
|
+
Apply, refresh, and retire always resolve those local files from the active config's
|
|
325
|
+
`baseline.artifactDirectory`. If you switch configs or target roots, Rehearsal refuses
|
|
326
|
+
to retire a receipt from the other target. It also refuses an existing receipt or
|
|
327
|
+
credential rather than overwriting or adopting it.
|
|
170
328
|
|
|
171
329
|
## Limits
|
|
172
330
|
|
package/docs/releasing.md
CHANGED
|
@@ -31,10 +31,13 @@ publication must change and prove the workflow before narrowing that permission.
|
|
|
31
31
|
|
|
32
32
|
1. Start from protected `main` on a dedicated ticketed release branch.
|
|
33
33
|
2. Verify the exact version, changelog, compatibility notes, and packed file list.
|
|
34
|
-
3. Run
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
3. Run `npm run release:verify`. It performs the package checks and every
|
|
35
|
+
installed-consumer scenario against one tarball, then records the exact package
|
|
36
|
+
version, SHA-256, environment, commands, timings, and results in
|
|
37
|
+
`test-results/release-gate/`. Run the dependency audit separately.
|
|
38
|
+
4. When an unfamiliar developer is available, have them follow clean-project onboarding.
|
|
39
|
+
Correct and retest the first confusing, missing, or wrong instruction. Record when
|
|
40
|
+
this human observation was unavailable; automated checks must not impersonate it.
|
|
38
41
|
5. Change `private` to `false` only in the reviewed release change.
|
|
39
42
|
6. Record the exact tarball filename, SHA-1, SHA-256, allowlisted files, unpacked size,
|
|
40
43
|
executable, declared runtime dependency inventory, and dependency audit result.
|
|
@@ -51,16 +54,25 @@ publication must change and prove the workflow before narrowing that permission.
|
|
|
51
54
|
11. Replace consuming projects' temporary Git/archive references only on their own
|
|
52
55
|
protected integration branches and rerun their complete verification.
|
|
53
56
|
|
|
54
|
-
The
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
The independent Rehearsal Test Lab is the primary pre-release consumer environment.
|
|
58
|
+
Real product integrations provide additional compatibility evidence; they do not
|
|
59
|
+
replace the package-owned release gate or Test Lab.
|
|
60
|
+
|
|
61
|
+
The workflow publishes beta and release-candidate versions under the `beta` dist-tag.
|
|
62
|
+
While Rehearsal has no stable release, it also moves `latest` to the same reviewed
|
|
63
|
+
prerelease. This keeps the npm package page and the ordinary
|
|
64
|
+
`npm install @rehearsal-db/core` command current. A stable version publishes under
|
|
65
|
+
`latest` without changing `beta`; after that point, later prereleases update only `beta`
|
|
66
|
+
and cannot replace the stable `latest` line. The GitHub prerelease setting must agree
|
|
67
|
+
with the package version or preparation fails.
|
|
68
|
+
|
|
69
|
+
The objective promotion checklist and compatibility boundary live in
|
|
70
|
+
[Stability and the first stable release](stability.md).
|
|
59
71
|
|
|
60
72
|
The trusted publisher allows `npm dist-tag` only so this workflow can maintain those two
|
|
61
|
-
tags without a stored npm token. A manual workflow run from `main` can repair the
|
|
62
|
-
for the exact
|
|
63
|
-
|
|
73
|
+
tags without a stored npm token. A manual workflow run from `main` can repair the correct
|
|
74
|
+
channel for the exact version currently recorded in `package.json`; it cannot publish a
|
|
75
|
+
package or select a different version. The protected `npm` environment still supplies
|
|
64
76
|
the human approval gate.
|
|
65
77
|
|
|
66
78
|
Creating the repository, passing CI, extracting the engine, merging a release branch,
|
package/docs/roadmap.md
CHANGED
|
@@ -29,8 +29,9 @@ Track the full breakdown in
|
|
|
29
29
|
invalid migrations, identities, images, persistence, reset, and cleanup.
|
|
30
30
|
- Run the released package in the real reporting consumer and record positives and
|
|
31
31
|
negatives.
|
|
32
|
-
- Directly observe any claimed Google account-picker/callback
|
|
33
|
-
onboarding behavior; automation cannot
|
|
32
|
+
- Directly observe any claimed Google account-picker/callback. Record
|
|
33
|
+
unfamiliar-developer onboarding behavior when a tester is available; automation cannot
|
|
34
|
+
invent either kind of human evidence.
|
|
34
35
|
- Remove consumer integration code only after its replacement passes and that deletion
|
|
35
36
|
is separately approved.
|
|
36
37
|
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Container runtime lifecycle
|
|
2
|
+
|
|
3
|
+
Rehearsal uses a local Docker-compatible engine for disposable PostgreSQL and Supabase
|
|
4
|
+
targets. It owns the targets it creates; it does not own the shared engine or another
|
|
5
|
+
project's containers.
|
|
6
|
+
|
|
7
|
+
## What starts Docker?
|
|
8
|
+
|
|
9
|
+
Read-only commands such as `doctor`, `status`, `candidates`, `explain`, and `inspect` do
|
|
10
|
+
not start Docker. Commands that create or resume a database—such as `start`, `reset`,
|
|
11
|
+
`run`, and `open`—need an already-running engine.
|
|
12
|
+
|
|
13
|
+
Generated configurations keep startup explicit:
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
containerRuntime: {
|
|
17
|
+
autoStartColima: false,
|
|
18
|
+
},
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
With the default, a stopped engine produces an actionable error. Start Docker Desktop,
|
|
22
|
+
Colima, Rancher Desktop, Podman with Docker compatibility, or another supported engine,
|
|
23
|
+
then repeat the command.
|
|
24
|
+
|
|
25
|
+
Setting `autoStartColima: true` is an explicit convenience opt-in. If Docker is
|
|
26
|
+
unavailable and the `colima` command exists, Rehearsal runs plain `colima start` and
|
|
27
|
+
reports it. Rehearsal does not resize Colima and does not stop the shared engine
|
|
28
|
+
automatically. Starting Docker can also wake unrelated containers that use Docker's
|
|
29
|
+
`always` or `unless-stopped` restart policy.
|
|
30
|
+
|
|
31
|
+
## What remains after a command?
|
|
32
|
+
|
|
33
|
+
- `run` stops the application proof process but keeps the database target available for
|
|
34
|
+
hands-on testing.
|
|
35
|
+
- `open` keeps the application and databases available until the application session is
|
|
36
|
+
interrupted. The database target remains available afterward.
|
|
37
|
+
- `stop` stops every configured Rehearsal target in reverse dependency order and retains
|
|
38
|
+
its local data.
|
|
39
|
+
- `start` resumes a stopped target, reusing compatible state.
|
|
40
|
+
- `reset` recreates the target from the active immutable baseline.
|
|
41
|
+
- `discard` removes the selected disposable target. It is the data-destructive runtime
|
|
42
|
+
operation and retains the immutable baseline.
|
|
43
|
+
|
|
44
|
+
After Supabase starts, Rehearsal changes only containers with the exact configured
|
|
45
|
+
Supabase project label to Docker's `no` restart policy. This does not remove containers
|
|
46
|
+
or volumes. It prevents a later Docker restart from silently waking stopped Rehearsal
|
|
47
|
+
stacks; `rehearsal start` still resumes them normally.
|
|
48
|
+
|
|
49
|
+
## A low-memory daily workflow
|
|
50
|
+
|
|
51
|
+
1. Start your Docker-compatible engine.
|
|
52
|
+
2. Run `rehearsal run` or `rehearsal open`.
|
|
53
|
+
3. When finished, run `rehearsal stop` from the project root.
|
|
54
|
+
4. Check other projects before stopping the shared engine:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
docker ps
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
5. If nothing else needs Docker, stop the engine using its own command, such as
|
|
61
|
+
`colima stop`.
|
|
62
|
+
|
|
63
|
+
Rehearsal intentionally does not infer that every running container belongs to it. It
|
|
64
|
+
also never runs a global Docker prune. Database and Storage volumes are not deleted by
|
|
65
|
+
`stop`.
|
|
66
|
+
|
|
67
|
+
## Choosing PostgreSQL or Supabase
|
|
68
|
+
|
|
69
|
+
Use the PostgreSQL target for migration, schema, trigger, privacy, and ordinary relational
|
|
70
|
+
data checks that do not require Supabase services. It uses one database container.
|
|
71
|
+
|
|
72
|
+
Use the Supabase target when the proof needs Auth, Storage, PostgREST, or the local API
|
|
73
|
+
gateway. Rehearsal already excludes Realtime, Edge Runtime, Analytics/Logflare, and Vector
|
|
74
|
+
from its Supabase stack. A future service-profile feature will make additional optional
|
|
75
|
+
services explicit; until then, do not trade away application fidelity merely to reduce a
|
|
76
|
+
container count.
|
|
77
|
+
|
|
78
|
+
## Diagnosing unexpected activity
|
|
79
|
+
|
|
80
|
+
Start with read-only checks:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
docker context show
|
|
84
|
+
docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Label "com.supabase.cli.project"}}'
|
|
85
|
+
docker stats --no-stream
|
|
86
|
+
colima status
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
For each container, inspect its project ownership and restart policy before taking any
|
|
90
|
+
action:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
docker inspect --format '{{json .Config.Labels}} {{.HostConfig.RestartPolicy.Name}}' CONTAINER
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Do not remove anonymous volumes or old images based on names alone. Use `rehearsal
|
|
97
|
+
cleanup` for package-owned baseline retention and its reviewed, opt-in image cleanup.
|
|
98
|
+
Shared resource inventory and stale-environment cleanup are tracked separately; until
|
|
99
|
+
that lands, stopping a configured target from its own project is the safe path.
|
package/docs/runtime-policies.md
CHANGED
|
@@ -77,9 +77,12 @@ graph without an application callback patch:
|
|
|
77
77
|
"identities": [
|
|
78
78
|
{
|
|
79
79
|
"name": "approved-owner",
|
|
80
|
-
"
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
"matcher": {
|
|
81
|
+
"type": "verified-email",
|
|
82
|
+
"providers": ["google"],
|
|
83
|
+
"emailEnvironmentVariable": "REHEARSAL_APPROVED_OWNER_EMAIL",
|
|
84
|
+
"approvedEmailSha256": "<sha256 of the lowercase approved email>"
|
|
85
|
+
},
|
|
83
86
|
"placeholderUserId": "11111111-1111-4111-8111-111111111111",
|
|
84
87
|
"references": [
|
|
85
88
|
{
|
|
@@ -152,8 +155,29 @@ graph without an application callback patch:
|
|
|
152
155
|
}
|
|
153
156
|
```
|
|
154
157
|
|
|
155
|
-
|
|
156
|
-
|
|
158
|
+
Authentication has three separate parts:
|
|
159
|
+
|
|
160
|
+
1. `config.supabase.authentication` can enable a Google or GitHub connection in local
|
|
161
|
+
Supabase and reads its credentials from the ignored owner-only environment file.
|
|
162
|
+
Existing projects may still own that local provider TOML manually. Email sign-in does
|
|
163
|
+
not use an OAuth credential declaration.
|
|
164
|
+
2. The application completes the ordinary sign-in and receives a normal Supabase
|
|
165
|
+
session. Rehearsal does not intercept the callback.
|
|
166
|
+
3. The identity policy matches that verified local identity and transfers only the
|
|
167
|
+
reviewed copied-account graph.
|
|
168
|
+
|
|
169
|
+
The email stays in an environment variable; only its reviewed hash is committed. The
|
|
170
|
+
guided command keeps the app available for ordinary sign-in, detects the reviewed local
|
|
171
|
+
Auth match, presents a redacted preview, and supplies the exact plan fingerprint
|
|
172
|
+
internally after one confirmation:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
npx rehearsal identity connect
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
It never intercepts provider credentials or reads browser state. After connection it
|
|
179
|
+
reopens the app; sign out and sign in once to receive fresh claims. Scripts may retain
|
|
180
|
+
the explicit plan and claim sequence:
|
|
157
181
|
|
|
158
182
|
```bash
|
|
159
183
|
npx rehearsal identity plan --identity=approved-owner
|
|
@@ -165,6 +189,50 @@ Rehearsal requires exactly one verified matching local provider identity. Every
|
|
|
165
189
|
`required` reference must exist after transfer. Declare application role tables as
|
|
166
190
|
references; `claims` alone is not a replacement for a database-backed token hook.
|
|
167
191
|
|
|
192
|
+
### Supported identity matchers
|
|
193
|
+
|
|
194
|
+
Rehearsal currently supports the Supabase provider values `email`, `google`, and
|
|
195
|
+
`github`. Other provider names fail closed until their Auth representation has package
|
|
196
|
+
coverage. Two matcher types are supported:
|
|
197
|
+
|
|
198
|
+
- `verified-email` accepts one or more supported providers. It lowercases the email from
|
|
199
|
+
the named environment variable and compares its SHA-256 receipt before querying Auth.
|
|
200
|
+
- `provider-subject` accepts one OAuth provider (`google` or `github`). It compares the
|
|
201
|
+
reviewed SHA-256 to Supabase's stable provider ID/subject without placing the raw
|
|
202
|
+
subject in the policy, baseline, command output, SQL parameters, or receipt.
|
|
203
|
+
|
|
204
|
+
Google by verified email:
|
|
205
|
+
|
|
206
|
+
```json
|
|
207
|
+
"matcher": {
|
|
208
|
+
"type": "verified-email",
|
|
209
|
+
"providers": ["google"],
|
|
210
|
+
"emailEnvironmentVariable": "REHEARSAL_APPROVED_OWNER_EMAIL",
|
|
211
|
+
"approvedEmailSha256": "<sha256 of the lowercase email>"
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Supabase email/password or magic-link sign-in uses the same matcher with
|
|
216
|
+
`"providers": ["email"]`. An account intentionally allowed to use either ordinary
|
|
217
|
+
email or Google can declare `"providers": ["email", "google"]`; the claim still refuses
|
|
218
|
+
zero or multiple matching identities.
|
|
219
|
+
|
|
220
|
+
GitHub by stable provider subject:
|
|
221
|
+
|
|
222
|
+
```json
|
|
223
|
+
"matcher": {
|
|
224
|
+
"type": "provider-subject",
|
|
225
|
+
"provider": "github",
|
|
226
|
+
"subjectEnvironmentVariable": "REHEARSAL_APPROVED_OWNER_SUBJECT",
|
|
227
|
+
"approvedSubjectSha256": "<sha256 of the exact GitHub subject>"
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Set the raw value only in the local shell or an ignored environment file. Existing
|
|
232
|
+
policies using the older top-level `provider`, `emailEnvironmentVariable`, and
|
|
233
|
+
`approvedEmailSha256` fields remain accepted as a single-provider verified-email
|
|
234
|
+
matcher. New policies should use the explicit `matcher` object.
|
|
235
|
+
|
|
168
236
|
References use `"strategy": "transfer"` by default. Use `"preserve-audit"` only for
|
|
169
237
|
immutable historical authorship, such as a completed review. Rehearsal leaves that row
|
|
170
238
|
and its synthetic Auth actor unchanged, but still transfers the active profile, roles,
|
|
@@ -179,9 +247,14 @@ or unrelated local application data rolls back the entire claim.
|
|
|
179
247
|
verifies the destination bytes, updates the declared database paths, and then removes
|
|
180
248
|
the old objects. A database failure removes the new copies and leaves the originals
|
|
181
249
|
usable. Restored objects may begin with either the placeholder owner or no owner;
|
|
182
|
-
another owner is refused. `pathReferences` updates matching text or JSONB pointers. A
|
|
183
|
-
`tokenHook` must return the declared claim subset before commit. The browser must then
|
|
250
|
+
another owner is refused. `pathReferences` updates matching text or JSONB pointers. A
|
|
251
|
+
configured `tokenHook` must return the declared claim subset before commit. The browser must then
|
|
184
252
|
refresh its session or sign in again because Rehearsal cannot rewrite an issued JWT.
|
|
253
|
+
Run `rehearsal open` again for that fresh-session check; runtime data is preserved.
|
|
254
|
+
|
|
255
|
+
After a claim, sign out and sign in again (or otherwise force a full token refresh) before
|
|
256
|
+
judging application roles. This preserves normal RLS, account blocks, role checks, and
|
|
257
|
+
MFA; identity association is not an authentication bypass.
|
|
185
258
|
|
|
186
259
|
The transaction does not import production passwords, sessions, refresh tokens,
|
|
187
260
|
cookies, MFA secrets, or provider credentials. Local MFA and authorization rules remain
|