Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9c65833954 | |||
| 6f5705fe02 |
@@ -0,0 +1,34 @@
|
|||||||
|
# P23 Dual-Write Closure — Decision (v0.12)
|
||||||
|
|
||||||
|
**Status**: DEFERRED to v1.x. The full deletion of the legacy CA
|
||||||
|
(`internal/security/ca.go`), mTLS transport (`internal/transport/mtls.go`),
|
||||||
|
and daemon plaintext mode is too large a refactor for v0.12 without
|
||||||
|
risking build stability. The legacy code is already marked Deprecated;
|
||||||
|
the step-ca + OIDC path (P04/P05/P07) is the primary identity layer.
|
||||||
|
|
||||||
|
## What v0.12 did close
|
||||||
|
|
||||||
|
- P07 removed all password paths (step-ca `--password-file`, Proxmox
|
||||||
|
`--password`, KindToken always-denies).
|
||||||
|
- P09 removed daemon plaintext mode (Start() requires mTLS).
|
||||||
|
- P11 added SVID chain validation (VerifySVIDWithChain).
|
||||||
|
- P06 rewrote ACL to OIDC (KindToken deprecated).
|
||||||
|
|
||||||
|
## What remains for v1.x
|
||||||
|
|
||||||
|
- Delete `internal/security/ca.go` legacy CA (requires migrating
|
||||||
|
`orca init` + `orca cert *` to step-ca exclusively).
|
||||||
|
- Delete `internal/transport/mtls.go` deprecated path.
|
||||||
|
- Delete `internal/certpaths/` (v0.8 flat layout); `internal/paths/`
|
||||||
|
is the only layout.
|
||||||
|
- Migrate `rotate-lead`, `drain`, `cutover`, `recovery` from
|
||||||
|
`certpaths` to `paths`.
|
||||||
|
|
||||||
|
## Why not in v0.12
|
||||||
|
|
||||||
|
The legacy CA is load-bearing for `orca init` and 6+ CLI commands. A
|
||||||
|
big-bang deletion would require migrating all of them to step-ca in a
|
||||||
|
single phase, with high risk of breaking the build. v0.12 is a
|
||||||
|
security-hardening milestone; the dual-write window is a code-hygiene
|
||||||
|
issue, not a security vulnerability (the legacy CA is deprecated and
|
||||||
|
the new path is primary). v1.x will close it as a focused refactor.
|
||||||
@@ -189,7 +189,7 @@ func alreadyMigrated(dir string) bool {
|
|||||||
// added it; v0.11 is single-namespace-per-DB). This mirrors the
|
// added it; v0.11 is single-namespace-per-DB). This mirrors the
|
||||||
// internal/store/migrate.go pattern but operates on a copied DB.
|
// internal/store/migrate.go pattern but operates on a copied DB.
|
||||||
func migrateDBSchema(dbPath string) error {
|
func migrateDBSchema(dbPath string) error {
|
||||||
db, err := sql.Open("sqlite", dbPath+"?_pragma=journal_mode(WAL)")
|
db, err := sql.Open("sqlite", dbPath+"?_pragma=journal_mode(WAL)&_pragma=foreign_keys(ON)")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("open %s: %w", dbPath, err)
|
return fmt.Errorf("open %s: %w", dbPath, err)
|
||||||
}
|
}
|
||||||
@@ -273,6 +273,8 @@ func fileExists(path string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// copyFile copies src to dst preserving the file mode.
|
// copyFile copies src to dst preserving the file mode.
|
||||||
|
// copyFile copies src to dst atomically (temp + rename). REQ-137/F19:
|
||||||
|
// a crash mid-copy must not leave a partial DB file.
|
||||||
func copyFile(src, dst string) error {
|
func copyFile(src, dst string) error {
|
||||||
data, err := os.ReadFile(src)
|
data, err := os.ReadFile(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -282,7 +284,11 @@ func copyFile(src, dst string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return os.WriteFile(dst, data, info.Mode().Perm())
|
tmp := dst + ".tmp"
|
||||||
|
if err := os.WriteFile(tmp, data, info.Mode().Perm()); err != nil {
|
||||||
|
return fmt.Errorf("copyFile: write tmp: %w", err)
|
||||||
|
}
|
||||||
|
return os.Rename(tmp, dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCAImporter returns the package-level CA importer (set via
|
// GetCAImporter returns the package-level CA importer (set via
|
||||||
|
|||||||
Reference in New Issue
Block a user