Merge pull request #181 from bnema/remove-security-hardening-regression-doc
docs: remove internal security regression matrix
1 file · +0 -222
D docs/security-hardening-regression-matrix.md +0 -222
| @@ -1,222 +0,0 @@ | |||
| 1 | - | # Security Hardening Regression Matrix | |
| 2 | - | ||
| 3 | - | This matrix lists the behaviors that should be tested while implementing the security-hardening fixes from the audit. It is intentionally focused on regressions: normal Gordon workflows must continue to work while exploit paths are blocked. | |
| 4 | - | ||
| 5 | - | ## Registry uploads | |
| 6 | - | ||
| 7 | - | ### Normal behavior to preserve | |
| 8 | - | - Docker push of a small image succeeds. | |
| 9 | - | - Docker push with multiple layers succeeds when every layer is below the configured cumulative blob limit. | |
| 10 | - | - Chunked blob upload succeeds when the cumulative size remains below the new cumulative limit setting, tentatively named `max_blob_size` unless implementation chooses a clearer config name. | |
| 11 | - | - A final `PUT` with a valid digest finalizes the blob and returns OCI-compatible headers. | |
| 12 | - | - Existing `max_blob_chunk_size` behavior still rejects a single oversized chunk; this remains distinct from the cumulative per-blob/layer limit. | |
| 13 | - | ||
| 14 | - | ### Security behavior to verify | |
| 15 | - | - Repeated `PATCH` chunks cannot exceed the cumulative upload limit. | |
| 16 | - | - `Content-Length` larger than the remaining allowed size is rejected before writing when possible. | |
| 17 | - | - A rejected upload does not leave unbounded stale data on disk. | |
| 18 | - | - Cancel/cleanup paths remove upload temp files and upload locks. | |
| 19 | - | - Error response remains Docker Registry compatible (`413` / `SIZE_INVALID`). | |
| 20 | - | ||
| 21 | - | ### Suggested tests | |
| 22 | - | - Unit tests for filesystem blob append under and over cumulative size. | |
| 23 | - | - Handler tests for `PATCH` and final `PUT` over limit. | |
| 24 | - | - Integration/manual: push image with a large layer and confirm failure is clean. | |
| 25 | - | ||
| 26 | - | ## Deploy errors and logs | |
| 27 | - | ||
| 28 | - | ### Normal behavior to preserve | |
| 29 | - | - Successful deploy response still includes status, domain, and container ID. | |
| 30 | - | - Failed deploy still returns useful high-level error/cause/hint. | |
| 31 | - | - Operators with the new logs permission can still retrieve logs through `/admin/logs`. | |
| 32 | - | - CLI deploy displays helpful failure information without leaking raw secrets. | |
| 33 | - | ||
| 34 | - | ### Security behavior to verify | |
| 35 | - | - A token with only `admin:config:write` cannot receive raw container logs in `/admin/deploy` error responses. | |
| 36 | - | - Logs returned through log endpoints are redacted for common secret patterns. | |
| 37 | - | - `admin:status:read` no longer grants log read access. | |
| 38 | - | - `admin:*:*` remains compatible and can access logs. | |
| 39 | - | ||
| 40 | - | ### Suggested tests | |
| 41 | - | - Handler tests for deploy error response with and without `logs:read`. | |
| 42 | - | - Scope tests for `logs:read`, wildcard, and old `status:read` behavior. | |
| 43 | - | - Redactor table tests for `PASSWORD=`, `TOKEN=`, `SECRET=`, `API_KEY=`, `DATABASE_URL=`, and simple JSON fields. | |
| 44 | - | ||
| 45 | - | ## Admin scopes and compatibility | |
| 46 | - | ||
| 47 | - | ### Normal behavior to preserve | |
| 48 | - | - Existing `admin:*:*` tokens continue to work everywhere. | |
| 49 | - | - Existing `routes`, `config`, `secrets`, and `status` scopes keep their intended behavior. | |
| 50 | - | - Token exchange through `/auth/token` still works for admin scopes. | |
| 51 | - | ||
| 52 | - | ### Security behavior to verify | |
| 53 | - | - New sensitive resources such as `logs` and possibly `volumes` are parsed and enforced. | |
| 54 | - | - Unknown or malformed scopes remain ignored/denied, not accidentally allowed. | |
| 55 | - | ||
| 56 | - | ### Suggested tests | |
| 57 | - | - Domain auth scope parsing tests. | |
| 58 | - | - Admin middleware/handler tests for each sensitive endpoint. | |
| 59 | - | ||
| 60 | - | ## Auto-route env-file extraction | |
| 61 | - | ||
| 62 | - | ### Normal behavior to preserve | |
| 63 | - | - Valid `gordon.env-file` imports default env values for a newly created auto-route. | |
| 64 | - | - Existing env values still override image-provided defaults. | |
| 65 | - | - Secret reference rejection remains intact. | |
| 66 | - | - Auto-route without env-file remains unchanged. | |
| 67 | - | ||
| 68 | - | ### Security behavior to verify | |
| 69 | - | - Oversized env files are rejected before full memory read. | |
| 70 | - | - Disallowed paths (`/proc`, `/sys`, `/dev`, `/run`, `/var/run`, `/`, traversal) are rejected. | |
| 71 | - | - Failed env-file import does not prevent route/deploy behavior beyond the intended warning path unless explicitly designed. | |
| 72 | - | ||
| 73 | - | ### Suggested tests | |
| 74 | - | - Runtime extraction tests using a controlled reader larger than the limit. | |
| 75 | - | - Auto-route usecase tests for allowed/disallowed paths. | |
| 76 | - | - Tests confirming `${pass:...}` / `${sops:...}` refs remain rejected. | |
| 77 | - | ||
| 78 | - | ## Domain canonicalization and proxy routing | |
| 79 | - | ||
| 80 | - | ### Normal behavior to preserve | |
| 81 | - | - Existing lowercase route domains continue to resolve. | |
| 82 | - | - Registry domain still routes to registry. | |
| 83 | - | - External routes still resolve and retain SSRF protections. | |
| 84 | - | - Hostnames with expected public domains work through proxy. | |
| 85 | - | ||
| 86 | - | ### Security behavior to verify | |
| 87 | - | - `App.Example.com` and `app.example.com` map to the same canonical route. | |
| 88 | - | - Duplicate case-variant routes cannot be created. | |
| 89 | - | - Host with invalid port/trailing dot/case is handled consistently. | |
| 90 | - | - HTTP-to-HTTPS redirect does not reflect arbitrary unconfigured Host values. | |
| 91 | - | ||
| 92 | - | ### Suggested tests | |
| 93 | - | - Config service tests for add/update/list canonical route domains. | |
| 94 | - | - Auto-route tests for case variants. | |
| 95 | - | - Proxy handler tests for Host normalization. | |
| 96 | - | - Middleware tests for redirect target host validation. | |
| 97 | - | ||
| 98 | - | ## Volumes | |
| 99 | - | ||
| 100 | - | ### Normal behavior to preserve | |
| 101 | - | - Listing volumes still shows Gordon-managed volumes. | |
| 102 | - | - Dry-run prune still reports what would be removed. | |
| 103 | - | - Actual prune still removes unused Gordon-managed volumes. | |
| 104 | - | - In-use Gordon volumes are not removed. | |
| 105 | - | ||
| 106 | - | ### Security behavior to verify | |
| 107 | - | - Unused non-Gordon Docker volumes are not removed. | |
| 108 | - | - Volumes without explicit Gordon ownership metadata, preferably `gordon.managed=true`, are ignored; prefix-only matching is unsafe except as a constrained legacy fallback with dedicated tests. | |
| 109 | - | - Any new `volumes:read/write` scope is enforced correctly. | |
| 110 | - | ||
| 111 | - | ### Suggested tests | |
| 112 | - | - Volume service tests with mixed Gordon/non-Gordon, used/unused volumes. | |
| 113 | - | - Admin handler tests for permissions. | |
| 114 | - | - Manual: create an unrelated Docker volume, run Gordon prune dry-run/real, confirm it remains. | |
| 115 | - | ||
| 116 | - | ## Backups | |
| 117 | - | ||
| 118 | - | ### Normal behavior to preserve | |
| 119 | - | - Manual backup completes and appears in list. | |
| 120 | - | - Scheduled backup path format remains readable/listable. | |
| 121 | - | - Backup detect still finds supported DB attachments. | |
| 122 | - | - Existing backups can still be listed after filename format changes. | |
| 123 | - | ||
| 124 | - | ### Security behavior to verify | |
| 125 | - | - Two backups for same domain/db/schedule in the same second do not share tmp/final filenames. | |
| 126 | - | - Concurrent backups do not truncate each other. | |
| 127 | - | - Store uses unique tmp files and atomic rename. | |
| 128 | - | - Path traversal protections remain intact. | |
| 129 | - | ||
| 130 | - | ### Suggested tests | |
| 131 | - | - Filesystem storage tests with identical timestamps. | |
| 132 | - | - Concurrent store test with two readers and same domain/db/schedule. | |
| 133 | - | - List tests for old and new filename formats if compatibility is needed. | |
| 134 | - | ||
| 135 | - | ## Secrets and pass migration | |
| 136 | - | ||
| 137 | - | ### Normal behavior to preserve | |
| 138 | - | - `pass` backend still migrates existing env keys correctly. | |
| 139 | - | - Attachment env migration still works. | |
| 140 | - | - Unsafe backend still loads valid files under `dataDir/secrets` for development. | |
| 141 | - | - Existing env file parsing remains compatible. | |
| 142 | - | ||
| 143 | - | ### Security behavior to verify | |
| 144 | - | - Unsafe backend rejects `../` and absolute `auth.token_secret` paths. | |
| 145 | - | - Migration does not leave plaintext `.env.migrated` by default. | |
| 146 | - | - If an explicit keep/quarantine option exists, files are stored with restrictive permissions and loud warnings. | |
| 147 | - | ||
| 148 | - | ### Suggested tests | |
| 149 | - | - `loadSecret` path traversal tests. | |
| 150 | - | - Migration tests verifying plaintext source file removal/quarantine. | |
| 151 | - | - Permission tests where practical (`0600` files, `0700` dirs). | |
| 152 | - | ||
| 153 | - | ## Config snapshot | |
| 154 | - | ||
| 155 | - | ### Normal behavior to preserve | |
| 156 | - | - `/admin/config` still returns enough information for CLI/admin use. | |
| 157 | - | - Routes and network isolation status remain visible to authorized callers. | |
| 158 | - | ||
| 159 | - | ### Security behavior to verify | |
| 160 | - | - `data_dir` is hidden by default or only available under a deliberately stronger detailed mode. | |
| 161 | - | - External route targets are hidden/redacted by default or gated. | |
| 162 | - | - `config:read` behavior remains documented. | |
| 163 | - | ||
| 164 | - | ### Suggested tests | |
| 165 | - | - Admin config response tests for default and detailed modes. | |
| 166 | - | - CLI remote config tests if output shape changes. | |
| 167 | - | ||
| 168 | - | ## External image registries | |
| 169 | - | ||
| 170 | - | ### Normal behavior to preserve | |
| 171 | - | - Images in the Gordon registry deploy normally. | |
| 172 | - | - Explicitly allowlisted external registries deploy if configured. | |
| 173 | - | - Attachments still deploy from allowed sources. | |
| 174 | - | ||
| 175 | - | ### Security behavior to verify | |
| 176 | - | - `localhost`, loopback, private IP, link-local, metadata IP, and DNS resolving to private ranges are rejected unless a deliberate unsafe override exists. | |
| 177 | - | - Non-allowlisted external registries are rejected before Docker pull. | |
| 178 | - | - Error messages do not leak sensitive network details. | |
| 179 | - | ||
| 180 | - | ### Suggested tests | |
| 181 | - | - Image reference validation table tests. | |
| 182 | - | - Config tests for `allowed_registries`. | |
| 183 | - | - Container service tests ensuring rejected images do not call `PullImage`. | |
| 184 | - | ||
| 185 | - | ## Docker networks and runtime hardening | |
| 186 | - | ||
| 187 | - | ### Normal behavior to preserve | |
| 188 | - | - Default/compat profile keeps common apps and attachments working. | |
| 189 | - | - Attachments remain reachable by service alias where intended. | |
| 190 | - | - Network groups still work when configured. | |
| 191 | - | ||
| 192 | - | ### Security behavior to verify | |
| 193 | - | - `internal` network option is applied when configured. | |
| 194 | - | - Strict profile applies readonly rootfs/user/caps as designed. | |
| 195 | - | - `no-new-privileges:true` and cap dropping are preserved. | |
| 196 | - | - Compat profile behavior is documented and tested. | |
| 197 | - | ||
| 198 | - | ### Suggested tests | |
| 199 | - | - Docker adapter config construction tests. | |
| 200 | - | - Container service tests for network option propagation. | |
| 201 | - | - Manual smoke: deploy app + postgres attachment in compat profile. | |
| 202 | - | - Manual smoke: deploy simple read-only app in strict profile. | |
| 203 | - | ||
| 204 | - | ## Install, Dockerfile, and supply-chain | |
| 205 | - | ||
| 206 | - | ### Normal behavior to preserve | |
| 207 | - | - `install.sh` installs the binary on Linux/macOS. | |
| 208 | - | - GitHub composite action installs Gordon in CI. | |
| 209 | - | - Dockerfile builds successfully. | |
| 210 | - | ||
| 211 | - | ### Security behavior to verify | |
| 212 | - | - Tar extraction only extracts `gordon`. | |
| 213 | - | - Installed binary must be a regular file, not symlink/directory. | |
| 214 | - | - Permissions are explicit (`0755`). | |
| 215 | - | - Checksums/signatures are verified consistently. | |
| 216 | - | - Gitleaks output is clean or only contains allowlisted examples. | |
| 217 | - | ||
| 218 | - | ### Suggested tests | |
| 219 | - | - Shellcheck/manual review for install script. | |
| 220 | - | - Action script dry-run if practical. | |
| 221 | - | - Docker build smoke after version alignment. | |
| 222 | - | - Gitleaks on `git archive HEAD`, not local `.worktrees`. | |
| @@ -1,222 +0,0 @@ | |||||
| 1 | - | # Security Hardening Regression Matrix | |||
| 2 | - | ||||
| 3 | - | This matrix lists the behaviors that should be tested while implementing the security-hardening fixes from the audit. It is intentionally focused on regressions: normal Gordon workflows must continue to work while exploit paths are blocked. | |||
| 4 | - | ||||
| 5 | - | ## Registry uploads | |||
| 6 | - | ||||
| 7 | - | ### Normal behavior to preserve | |||
| 8 | - | - Docker push of a small image succeeds. | |||
| 9 | - | - Docker push with multiple layers succeeds when every layer is below the configured cumulative blob limit. | |||
| 10 | - | - Chunked blob upload succeeds when the cumulative size remains below the new cumulative limit setting, tentatively named `max_blob_size` unless implementation chooses a clearer config name. | |||
| 11 | - | - A final `PUT` with a valid digest finalizes the blob and returns OCI-compatible headers. | |||
| 12 | - | - Existing `max_blob_chunk_size` behavior still rejects a single oversized chunk; this remains distinct from the cumulative per-blob/layer limit. | |||
| 13 | - | ||||
| 14 | - | ### Security behavior to verify | |||
| 15 | - | - Repeated `PATCH` chunks cannot exceed the cumulative upload limit. | |||
| 16 | - | - `Content-Length` larger than the remaining allowed size is rejected before writing when possible. | |||
| 17 | - | - A rejected upload does not leave unbounded stale data on disk. | |||
| 18 | - | - Cancel/cleanup paths remove upload temp files and upload locks. | |||
| 19 | - | - Error response remains Docker Registry compatible (`413` / `SIZE_INVALID`). | |||
| 20 | - | ||||
| 21 | - | ### Suggested tests | |||
| 22 | - | - Unit tests for filesystem blob append under and over cumulative size. | |||
| 23 | - | - Handler tests for `PATCH` and final `PUT` over limit. | |||
| 24 | - | - Integration/manual: push image with a large layer and confirm failure is clean. | |||
| 25 | - | ||||
| 26 | - | ## Deploy errors and logs | |||
| 27 | - | ||||
| 28 | - | ### Normal behavior to preserve | |||
| 29 | - | - Successful deploy response still includes status, domain, and container ID. | |||
| 30 | - | - Failed deploy still returns useful high-level error/cause/hint. | |||
| 31 | - | - Operators with the new logs permission can still retrieve logs through `/admin/logs`. | |||
| 32 | - | - CLI deploy displays helpful failure information without leaking raw secrets. | |||
| 33 | - | ||||
| 34 | - | ### Security behavior to verify | |||
| 35 | - | - A token with only `admin:config:write` cannot receive raw container logs in `/admin/deploy` error responses. | |||
| 36 | - | - Logs returned through log endpoints are redacted for common secret patterns. | |||
| 37 | - | - `admin:status:read` no longer grants log read access. | |||
| 38 | - | - `admin:*:*` remains compatible and can access logs. | |||
| 39 | - | ||||
| 40 | - | ### Suggested tests | |||
| 41 | - | - Handler tests for deploy error response with and without `logs:read`. | |||
| 42 | - | - Scope tests for `logs:read`, wildcard, and old `status:read` behavior. | |||
| 43 | - | - Redactor table tests for `PASSWORD=`, `TOKEN=`, `SECRET=`, `API_KEY=`, `DATABASE_URL=`, and simple JSON fields. | |||
| 44 | - | ||||
| 45 | - | ## Admin scopes and compatibility | |||
| 46 | - | ||||
| 47 | - | ### Normal behavior to preserve | |||
| 48 | - | - Existing `admin:*:*` tokens continue to work everywhere. | |||
| 49 | - | - Existing `routes`, `config`, `secrets`, and `status` scopes keep their intended behavior. | |||
| 50 | - | - Token exchange through `/auth/token` still works for admin scopes. | |||
| 51 | - | ||||
| 52 | - | ### Security behavior to verify | |||
| 53 | - | - New sensitive resources such as `logs` and possibly `volumes` are parsed and enforced. | |||
| 54 | - | - Unknown or malformed scopes remain ignored/denied, not accidentally allowed. | |||
| 55 | - | ||||
| 56 | - | ### Suggested tests | |||
| 57 | - | - Domain auth scope parsing tests. | |||
| 58 | - | - Admin middleware/handler tests for each sensitive endpoint. | |||
| 59 | - | ||||
| 60 | - | ## Auto-route env-file extraction | |||
| 61 | - | ||||
| 62 | - | ### Normal behavior to preserve | |||
| 63 | - | - Valid `gordon.env-file` imports default env values for a newly created auto-route. | |||
| 64 | - | - Existing env values still override image-provided defaults. | |||
| 65 | - | - Secret reference rejection remains intact. | |||
| 66 | - | - Auto-route without env-file remains unchanged. | |||
| 67 | - | ||||
| 68 | - | ### Security behavior to verify | |||
| 69 | - | - Oversized env files are rejected before full memory read. | |||
| 70 | - | - Disallowed paths (`/proc`, `/sys`, `/dev`, `/run`, `/var/run`, `/`, traversal) are rejected. | |||
| 71 | - | - Failed env-file import does not prevent route/deploy behavior beyond the intended warning path unless explicitly designed. | |||
| 72 | - | ||||
| 73 | - | ### Suggested tests | |||
| 74 | - | - Runtime extraction tests using a controlled reader larger than the limit. | |||
| 75 | - | - Auto-route usecase tests for allowed/disallowed paths. | |||
| 76 | - | - Tests confirming `${pass:...}` / `${sops:...}` refs remain rejected. | |||
| 77 | - | ||||
| 78 | - | ## Domain canonicalization and proxy routing | |||
| 79 | - | ||||
| 80 | - | ### Normal behavior to preserve | |||
| 81 | - | - Existing lowercase route domains continue to resolve. | |||
| 82 | - | - Registry domain still routes to registry. | |||
| 83 | - | - External routes still resolve and retain SSRF protections. | |||
| 84 | - | - Hostnames with expected public domains work through proxy. | |||
| 85 | - | ||||
| 86 | - | ### Security behavior to verify | |||
| 87 | - | - `App.Example.com` and `app.example.com` map to the same canonical route. | |||
| 88 | - | - Duplicate case-variant routes cannot be created. | |||
| 89 | - | - Host with invalid port/trailing dot/case is handled consistently. | |||
| 90 | - | - HTTP-to-HTTPS redirect does not reflect arbitrary unconfigured Host values. | |||
| 91 | - | ||||
| 92 | - | ### Suggested tests | |||
| 93 | - | - Config service tests for add/update/list canonical route domains. | |||
| 94 | - | - Auto-route tests for case variants. | |||
| 95 | - | - Proxy handler tests for Host normalization. | |||
| 96 | - | - Middleware tests for redirect target host validation. | |||
| 97 | - | ||||
| 98 | - | ## Volumes | |||
| 99 | - | ||||
| 100 | - | ### Normal behavior to preserve | |||
| 101 | - | - Listing volumes still shows Gordon-managed volumes. | |||
| 102 | - | - Dry-run prune still reports what would be removed. | |||
| 103 | - | - Actual prune still removes unused Gordon-managed volumes. | |||
| 104 | - | - In-use Gordon volumes are not removed. | |||
| 105 | - | ||||
| 106 | - | ### Security behavior to verify | |||
| 107 | - | - Unused non-Gordon Docker volumes are not removed. | |||
| 108 | - | - Volumes without explicit Gordon ownership metadata, preferably `gordon.managed=true`, are ignored; prefix-only matching is unsafe except as a constrained legacy fallback with dedicated tests. | |||
| 109 | - | - Any new `volumes:read/write` scope is enforced correctly. | |||
| 110 | - | ||||
| 111 | - | ### Suggested tests | |||
| 112 | - | - Volume service tests with mixed Gordon/non-Gordon, used/unused volumes. | |||
| 113 | - | - Admin handler tests for permissions. | |||
| 114 | - | - Manual: create an unrelated Docker volume, run Gordon prune dry-run/real, confirm it remains. | |||
| 115 | - | ||||
| 116 | - | ## Backups | |||
| 117 | - | ||||
| 118 | - | ### Normal behavior to preserve | |||
| 119 | - | - Manual backup completes and appears in list. | |||
| 120 | - | - Scheduled backup path format remains readable/listable. | |||
| 121 | - | - Backup detect still finds supported DB attachments. | |||
| 122 | - | - Existing backups can still be listed after filename format changes. | |||
| 123 | - | ||||
| 124 | - | ### Security behavior to verify | |||
| 125 | - | - Two backups for same domain/db/schedule in the same second do not share tmp/final filenames. | |||
| 126 | - | - Concurrent backups do not truncate each other. | |||
| 127 | - | - Store uses unique tmp files and atomic rename. | |||
| 128 | - | - Path traversal protections remain intact. | |||
| 129 | - | ||||
| 130 | - | ### Suggested tests | |||
| 131 | - | - Filesystem storage tests with identical timestamps. | |||
| 132 | - | - Concurrent store test with two readers and same domain/db/schedule. | |||
| 133 | - | - List tests for old and new filename formats if compatibility is needed. | |||
| 134 | - | ||||
| 135 | - | ## Secrets and pass migration | |||
| 136 | - | ||||
| 137 | - | ### Normal behavior to preserve | |||
| 138 | - | - `pass` backend still migrates existing env keys correctly. | |||
| 139 | - | - Attachment env migration still works. | |||
| 140 | - | - Unsafe backend still loads valid files under `dataDir/secrets` for development. | |||
| 141 | - | - Existing env file parsing remains compatible. | |||
| 142 | - | ||||
| 143 | - | ### Security behavior to verify | |||
| 144 | - | - Unsafe backend rejects `../` and absolute `auth.token_secret` paths. | |||
| 145 | - | - Migration does not leave plaintext `.env.migrated` by default. | |||
| 146 | - | - If an explicit keep/quarantine option exists, files are stored with restrictive permissions and loud warnings. | |||
| 147 | - | ||||
| 148 | - | ### Suggested tests | |||
| 149 | - | - `loadSecret` path traversal tests. | |||
| 150 | - | - Migration tests verifying plaintext source file removal/quarantine. | |||
| 151 | - | - Permission tests where practical (`0600` files, `0700` dirs). | |||
| 152 | - | ||||
| 153 | - | ## Config snapshot | |||
| 154 | - | ||||
| 155 | - | ### Normal behavior to preserve | |||
| 156 | - | - `/admin/config` still returns enough information for CLI/admin use. | |||
| 157 | - | - Routes and network isolation status remain visible to authorized callers. | |||
| 158 | - | ||||
| 159 | - | ### Security behavior to verify | |||
| 160 | - | - `data_dir` is hidden by default or only available under a deliberately stronger detailed mode. | |||
| 161 | - | - External route targets are hidden/redacted by default or gated. | |||
| 162 | - | - `config:read` behavior remains documented. | |||
| 163 | - | ||||
| 164 | - | ### Suggested tests | |||
| 165 | - | - Admin config response tests for default and detailed modes. | |||
| 166 | - | - CLI remote config tests if output shape changes. | |||
| 167 | - | ||||
| 168 | - | ## External image registries | |||
| 169 | - | ||||
| 170 | - | ### Normal behavior to preserve | |||
| 171 | - | - Images in the Gordon registry deploy normally. | |||
| 172 | - | - Explicitly allowlisted external registries deploy if configured. | |||
| 173 | - | - Attachments still deploy from allowed sources. | |||
| 174 | - | ||||
| 175 | - | ### Security behavior to verify | |||
| 176 | - | - `localhost`, loopback, private IP, link-local, metadata IP, and DNS resolving to private ranges are rejected unless a deliberate unsafe override exists. | |||
| 177 | - | - Non-allowlisted external registries are rejected before Docker pull. | |||
| 178 | - | - Error messages do not leak sensitive network details. | |||
| 179 | - | ||||
| 180 | - | ### Suggested tests | |||
| 181 | - | - Image reference validation table tests. | |||
| 182 | - | - Config tests for `allowed_registries`. | |||
| 183 | - | - Container service tests ensuring rejected images do not call `PullImage`. | |||
| 184 | - | ||||
| 185 | - | ## Docker networks and runtime hardening | |||
| 186 | - | ||||
| 187 | - | ### Normal behavior to preserve | |||
| 188 | - | - Default/compat profile keeps common apps and attachments working. | |||
| 189 | - | - Attachments remain reachable by service alias where intended. | |||
| 190 | - | - Network groups still work when configured. | |||
| 191 | - | ||||
| 192 | - | ### Security behavior to verify | |||
| 193 | - | - `internal` network option is applied when configured. | |||
| 194 | - | - Strict profile applies readonly rootfs/user/caps as designed. | |||
| 195 | - | - `no-new-privileges:true` and cap dropping are preserved. | |||
| 196 | - | - Compat profile behavior is documented and tested. | |||
| 197 | - | ||||
| 198 | - | ### Suggested tests | |||
| 199 | - | - Docker adapter config construction tests. | |||
| 200 | - | - Container service tests for network option propagation. | |||
| 201 | - | - Manual smoke: deploy app + postgres attachment in compat profile. | |||
| 202 | - | - Manual smoke: deploy simple read-only app in strict profile. | |||
| 203 | - | ||||
| 204 | - | ## Install, Dockerfile, and supply-chain | |||
| 205 | - | ||||
| 206 | - | ### Normal behavior to preserve | |||
| 207 | - | - `install.sh` installs the binary on Linux/macOS. | |||
| 208 | - | - GitHub composite action installs Gordon in CI. | |||
| 209 | - | - Dockerfile builds successfully. | |||
| 210 | - | ||||
| 211 | - | ### Security behavior to verify | |||
| 212 | - | - Tar extraction only extracts `gordon`. | |||
| 213 | - | - Installed binary must be a regular file, not symlink/directory. | |||
| 214 | - | - Permissions are explicit (`0755`). | |||
| 215 | - | - Checksums/signatures are verified consistently. | |||
| 216 | - | - Gitleaks output is clean or only contains allowlisted examples. | |||
| 217 | - | ||||
| 218 | - | ### Suggested tests | |||
| 219 | - | - Shellcheck/manual review for install script. | |||
| 220 | - | - Action script dry-run if practical. | |||
| 221 | - | - Docker build smoke after version alignment. | |||
| 222 | - | - Gitleaks on `git archive HEAD`, not local `.worktrees`. | |||