localhost1978's picture
download
raw
12.7 kB
import Foundation
import Testing
import SSK_Abstractions
@testable import SSK_DocGen
@Suite("P0-3 Security Boundaries")
struct ACPSecurityBoundaryTests {
// MARK: - 1 & 2. Workspace Root & Symlink Boundaries
@Test("Workspace root is canonicalized and validated before scanning")
func testWorkspaceRootValidation() throws {
let tmpDir = FileManager.default.temporaryDirectory
.appendingPathComponent("P03Test-\(UUID().uuidString)", isDirectory: true)
try FileManager.default.createDirectory(at: tmpDir, withIntermediateDirectories: true)
defer { try? FileManager.default.removeItem(at: tmpDir) }
let workspace = tmpDir.appendingPathComponent("workspace", isDirectory: true)
try FileManager.default.createDirectory(at: workspace, withIntermediateDirectories: true)
let validator = try ApprovedPathValidator(workspaceURL: workspace)
#expect(validator.workspaceRoot.path == workspace.standardizedFileURL.path)
}
@Test("Symlink escape outside approved root is strictly rejected")
func testSymlinkEscapeRejection() throws {
let tmpDir = FileManager.default.temporaryDirectory
.appendingPathComponent("P03Escape-\(UUID().uuidString)", isDirectory: true)
let workspace = tmpDir.appendingPathComponent("workspace", isDirectory: true)
let outside = tmpDir.appendingPathComponent("outside", isDirectory: true)
try FileManager.default.createDirectory(at: workspace, withIntermediateDirectories: true)
try FileManager.default.createDirectory(at: outside, withIntermediateDirectories: true)
defer { try? FileManager.default.removeItem(at: tmpDir) }
let secretFile = outside.appendingPathComponent("secret.txt")
try "secret content".write(to: secretFile, atomically: true, encoding: .utf8)
let linkInWorkspace = workspace.appendingPathComponent("symlink.txt")
try FileManager.default.createSymbolicLink(at: linkInWorkspace, withDestinationURL: secretFile)
let validator = try ApprovedPathValidator(workspaceURL: workspace)
#expect(throws: ApprovedPathValidationError.self) {
try validator.workspacePath(for: linkInWorkspace)
}
}
// MARK: - 3 & 4. Resource Allowlist & Typed Errors
private struct DummyReader: ACPResourceReading {
func read(_ resource: ACPResourceRegistration) async throws -> String {
throw ACPResourceReadError.resourceNotFound
}
}
@Test("Missing resource returns typed resourceNotFound error code -32004")
func testMissingResourceTypedError() async throws {
let workspace = FileManager.default.temporaryDirectory
.appendingPathComponent("P03Res-\(UUID().uuidString)", isDirectory: true)
try FileManager.default.createDirectory(at: workspace, withIntermediateDirectories: true)
defer { try? FileManager.default.removeItem(at: workspace) }
let context = try ACPRequestContext(workspaceURL: workspace)
let service = ACPService(context: context, resourceReader: DummyReader())
let request = "{\"jsonrpc\":\"2.0\",\"id\":101,\"method\":\"resources/read\",\"params\":{\"uri\":\"file:///SSK_Ledger_Vault/unknown_file.json\"}}"
let responseData = await service.response(for: request)
let data = try #require(responseData)
let response = try JSONSerialization.jsonObject(with: data) as! [String: Any]
let error = try #require(response["error"] as? [String: Any])
#expect(error["code"] as? Int == -32004)
#expect((error["message"] as? String)?.contains("resource") == true)
}
// MARK: - 5. Redaction of Absolute Source Paths
@Test("Absolute file paths are redacted in text and JSON responses")
func testAbsolutePathRedaction() {
let jsonWithPaths = "{\"source\": \"/Users/voxels/SovereignSurvivalKit/src/Secret.swift\", \"uri\": \"file:///Users/voxels/Internal.swift\"}"
let redacted = ACPResourceContentRedactor.redactingAbsolutePaths(in: jsonWithPaths)
#expect(!redacted.contains("/Users/voxels"))
#expect(redacted.contains("<redacted-path>"))
}
// MARK: - 6. Authorization Enforcement
@Test("Curation update without valid token is rejected with code -32001")
func testCurationAuthorizationFailure() async throws {
let workspace = FileManager.default.temporaryDirectory
.appendingPathComponent("P03Auth-\(UUID().uuidString)", isDirectory: true)
try FileManager.default.createDirectory(at: workspace, withIntermediateDirectories: true)
defer { try? FileManager.default.removeItem(at: workspace) }
let context = try ACPRequestContext(workspaceURL: workspace)
let service = ACPService(context: context)
let unauthReq = "{\"jsonrpc\":\"2.0\",\"id\":201,\"method\":\"tools/call\",\"params\":{\"name\":\"update_curation_state\",\"arguments\":{\"tokenId\":\"entity-1\",\"state\":\"accept\"}}}"
let responseData = await service.response(for: unauthReq)
let data = try #require(responseData)
let response = try JSONSerialization.jsonObject(with: data) as! [String: Any]
let error = try #require(response["error"] as? [String: Any])
#expect(error["code"] as? Int == -32001)
}
// MARK: - 7. Curation State Transitions & Idempotency
@Test("Curation state transitions perform token lookup, audit log creation, and idempotency")
func testCurationStateTransitionAndIdempotency() async throws {
let workspace = FileManager.default.temporaryDirectory
.appendingPathComponent("P03Cur-\(UUID().uuidString)", isDirectory: true)
try FileManager.default.createDirectory(at: workspace, withIntermediateDirectories: true)
defer { try? FileManager.default.removeItem(at: workspace) }
let context = try ACPRequestContext(workspaceURL: workspace)
await context.curationManager.registerToken(id: "token-ast-101", state: .defer)
let service = ACPService(context: context)
// 1. Initial State Transition: defer -> accept
let req1 = "{\"jsonrpc\":\"2.0\",\"id\":301,\"method\":\"tools/call\",\"params\":{\"name\":\"update_curation_state\",\"arguments\":{\"tokenId\":\"token-ast-101\",\"state\":\"accept\",\"authorization\":\"ssk_curation_token_valid\"}}}"
let data1 = try #require(await service.response(for: req1))
let res1 = try JSONSerialization.jsonObject(with: data1) as! [String: Any]
let result1 = try #require(res1["result"] as? [String: Any])
#expect(result1["tokenId"] as? String == "token-ast-101")
#expect(result1["previousState"] as? String == "defer")
#expect(result1["currentState"] as? String == "accept")
#expect(result1["idempotent"] as? Bool == false)
// 2. Idempotent Transition: accept -> accept
let req2 = "{\"jsonrpc\":\"2.0\",\"id\":302,\"method\":\"tools/call\",\"params\":{\"name\":\"update_curation_state\",\"arguments\":{\"tokenId\":\"token-ast-101\",\"state\":\"accept\",\"authorization\":\"ssk_curation_token_valid\"}}}"
let data2 = try #require(await service.response(for: req2))
let res2 = try JSONSerialization.jsonObject(with: data2) as! [String: Any]
let result2 = try #require(res2["result"] as? [String: Any])
#expect(result2["previousState"] as? String == "accept")
#expect(result2["currentState"] as? String == "accept")
#expect(result2["idempotent"] as? Bool == true)
// 3. Unknown Token Lookup Failure (code -32004)
let req3 = "{\"jsonrpc\":\"2.0\",\"id\":303,\"method\":\"tools/call\",\"params\":{\"name\":\"update_curation_state\",\"arguments\":{\"tokenId\":\"unknown-token-999\",\"state\":\"accept\",\"authorization\":\"ssk_curation_token_valid\"}}}"
let data3 = try #require(await service.response(for: req3))
let res3 = try JSONSerialization.jsonObject(with: data3) as! [String: Any]
let error3 = try #require(res3["error"] as? [String: Any])
#expect(error3["code"] as? Int == -32004)
}
// MARK: - 8. Identity & Settlement Synthesis Checks
@Test("Synthesis requires identity claims verification and settlement checks")
func testSynthesisIdentityAndSettlement() async throws {
let workspace = FileManager.default.temporaryDirectory
.appendingPathComponent("P03Synth-\(UUID().uuidString)", isDirectory: true)
try FileManager.default.createDirectory(at: workspace, withIntermediateDirectories: true)
defer { try? FileManager.default.removeItem(at: workspace) }
let context = try ACPRequestContext(workspaceURL: workspace)
let service = ACPService(context: context)
// 1. Invalid Identity (age < 18) -> Code -32002
let badIdReq = "{\"jsonrpc\":\"2.0\",\"id\":401,\"method\":\"tools/call\",\"params\":{\"name\":\"synthesize_media\",\"arguments\":{\"payload\":\"sample\",\"authorization\":\"ssk_synthesis_token_valid\",\"identity\":{\"age\":15,\"stateSignature\":\"sig\",\"jurisdiction\":\"US-CA\"}}}}"
let dataBadId = try #require(await service.response(for: badIdReq))
let resBadId = try JSONSerialization.jsonObject(with: dataBadId) as! [String: Any]
let errBadId = try #require(resBadId["error"] as? [String: Any])
#expect(errBadId["code"] as? Int == -32002)
// 2. Failed Settlement (sealIntact: false) -> Code -32007
let badSettReq = "{\"jsonrpc\":\"2.0\",\"id\":402,\"method\":\"tools/call\",\"params\":{\"name\":\"synthesize_media\",\"arguments\":{\"payload\":\"sample\",\"authorization\":\"ssk_synthesis_token_valid\",\"identity\":{\"age\":25,\"stateSignature\":\"sig\",\"jurisdiction\":\"US-CA\"},\"settlement\":{\"sealIntact\":false}}}}"
let dataBadSett = try #require(await service.response(for: badSettReq))
let resBadSett = try JSONSerialization.jsonObject(with: dataBadSett) as! [String: Any]
let errBadSett = try #require(resBadSett["error"] as? [String: Any])
#expect(errBadSett["code"] as? Int == -32007)
// 3. Valid Synthesis
let validReq = "{\"jsonrpc\":\"2.0\",\"id\":403,\"method\":\"tools/call\",\"params\":{\"name\":\"synthesize_media\",\"arguments\":{\"payload\":\"sample_media_data\",\"authorization\":\"ssk_synthesis_token_valid\",\"identity\":{\"age\":25,\"stateSignature\":\"sig_valid\",\"jurisdiction\":\"US-CA\"},\"settlement\":{\"sealIntact\":true,\"localityVerified\":true,\"psiScore\":1.0}}}}"
let dataValid = try #require(await service.response(for: validReq))
let resValid = try JSONSerialization.jsonObject(with: dataValid) as! [String: Any]
let resultValid = try #require(resValid["result"] as? [String: Any])
#expect(resultValid["status"] as? String == "synthesized")
#expect(resultValid["identityVerified"] as? Bool == true)
#expect(resultValid["settlementVerified"] as? Bool == true)
}
// MARK: - 9. Signature & Artifact Tamper Tests
@Test("Tampering with signature payload invalidates verification")
func testSignatureTamperDetection() {
let originalPayload = "CandidateGraph(nodeId: node1, edges: [e1, e2])"
let validSignatureBytes: [UInt8] = [0xAA, 0xBB, 0xCC, 0xDD]
// TODO: Replace this simulated verification with real cryptographic verification (e.g. CryptoKit)
// Simulated verification function
func verify(payload: String, signature: [UInt8]) -> Bool {
let expectedSig: [UInt8] = [0xAA, 0xBB, 0xCC, 0xDD]
return payload == originalPayload && signature == expectedSig
}
#expect(verify(payload: originalPayload, signature: validSignatureBytes))
// 1. Tamper with payload
#expect(!verify(payload: "CandidateGraph(nodeId: node1, edges: [e1, TAMPERED])", signature: validSignatureBytes))
// 2. Tamper with signature
var tamperedSig = validSignatureBytes
tamperedSig[0] ^= 0xFF
#expect(!verify(payload: originalPayload, signature: tamperedSig))
}
@Test("Tampering with ledger artifact JSON structures is detected")
func testArtifactTamperDetection() {
let validJSON = "{\"version\":\"1.0\",\"entities\":[{\"name\":\"EntityA\",\"line\":10}]}"
let corruptedJSON = "{\"version\":\"1.0\",\"entities\":[{\"name\":\"EntityA\"" // Truncated
let validData = validJSON.data(using: .utf8)!
let corruptedData = corruptedJSON.data(using: .utf8)!
#expect((try? JSONSerialization.jsonObject(with: validData)) != nil)
#expect((try? JSONSerialization.jsonObject(with: corruptedData)) == nil)
}
}

Xet Storage Details

Size:
12.7 kB
·
Xet hash:
dadbf22c314b25a551d992a68ae36b715721de56f22a5d299fdb278881af3010

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.