mirror of
https://github.com/hanzoai/drive.git
synced 2026-10-30 18:38:28 +00:00
Hash-chained, append-only audit log per tenant: every mkdir/upload/download/ share (and denied access) records actor/action/resource with a sha256 chain over the prior entry. VerifyAudit() recomputes the chain and reports the first tampered seq — altering or deleting any entry is detected (SOC 2 CC7.2). GET /v1/drive/audit exports the trail + intact status for auditors. SOC2-READINESS.md maps Trust Services Criteria to code vs org process — honest that readiness != certification (needs an auditor + observation window). Co-authored-by: Hanzo Dev <[email protected]>
38 lines
1.3 KiB
Go
38 lines
1.3 KiB
Go
package drive_test
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/hanzoai/drive"
|
|
_ "github.com/hanzoai/sqlite3/embed"
|
|
"github.com/hanzoai/vfs/pkg/backend"
|
|
_ "github.com/hanzoai/vfs/pkg/backend/file"
|
|
"github.com/luxfi/age"
|
|
)
|
|
|
|
func TestAuditTamperEvident(t *testing.T) {
|
|
ctx := context.Background()
|
|
be, _ := backend.Open(ctx, "file://"+t.TempDir())
|
|
st, _ := drive.Open("file:"+t.TempDir()+"/m.db", be)
|
|
defer st.Close()
|
|
owner, _ := age.GenerateHybridIdentity()
|
|
|
|
f, _ := st.Mkdir("", "docs")
|
|
st.Audit("[email protected]", "mkdir", f.ID, "docs")
|
|
n, _ := st.Upload(ctx, f.ID, "a.txt", strings.NewReader("x"), owner.Recipient())
|
|
st.Audit("[email protected]", "upload", n.ID, "a.txt")
|
|
st.Audit("[email protected]", "download", n.ID, "")
|
|
|
|
trail, _ := st.AuditTrail(10)
|
|
if len(trail) != 3 { t.Fatalf("trail len=%d want 3", len(trail)) }
|
|
if at, _ := st.VerifyAudit(); at != 0 { t.Fatalf("intact chain flagged tamper at %d", at) }
|
|
|
|
// tamper: rewrite an actor in place (the classic "cover your tracks") — chain must break
|
|
st.Exec(`UPDATE audit SET actor='nobody' WHERE action='download'`)
|
|
at, _ := st.VerifyAudit()
|
|
if at == 0 { t.Fatal("tamper NOT detected — audit log is not tamper-evident") }
|
|
t.Logf("tamper detected at seq %d — hash chain holds (SOC2 CC7.2)", at)
|
|
}
|