// // SecureKeyStoreTests.swift // Zyquo Atlas // // Author: Simon-Pierre Boucher // Mail: contact@spboucher.ai // import Foundation import Testing @testable import ZyquoAtlas @Suite struct SecureKeyStoreTests { private func temporaryVaultURL() -> URL { FileManager.default.temporaryDirectory .appendingPathComponent("zyquo-tests-\(UUID().uuidString)") .appendingPathComponent("vault.zq") } @Test func encryptDecryptRoundTrip() throws { let url = temporaryVaultURL() defer { try? FileManager.default.removeItem(at: url.deletingLastPathComponent()) } let store = SecureKeyStore(vaultURL: url) let keys = [ "openai": "sk-proj-test-1234", "anthropic": "sk-ant-test-5678", "mistral": "plainkey", ] try store.saveKeys(keys) let loaded = try store.loadKeys() #expect(loaded == keys) // Vault file must not contain any key material in plaintext. let raw = try Data(contentsOf: url) let rawString = String(decoding: raw, as: UTF8.self) #expect(!rawString.contains("sk-proj-test-1234")) #expect(!rawString.contains("sk-ant-test-5678")) #expect(!rawString.contains("openai")) } @Test func perProviderSetGetDelete() throws { let url = temporaryVaultURL() defer { try? FileManager.default.removeItem(at: url.deletingLastPathComponent()) } let store = SecureKeyStore(vaultURL: url) try store.setKey("xai-abc", for: .xai) try store.setKey("pplx-def", for: .perplexity) #expect(try store.key(for: .xai) == "xai-abc") #expect(try store.key(for: .perplexity) == "pplx-def") try store.deleteKey(for: .xai) #expect(try store.key(for: .xai) == nil) #expect(try store.key(for: .perplexity) == "pplx-def") } @Test func emptyVaultLoadsEmpty() throws { let store = SecureKeyStore(vaultURL: temporaryVaultURL()) #expect(try store.loadKeys().isEmpty) } @Test func tamperedVaultThrowsCorrupted() throws { let url = temporaryVaultURL() defer { try? FileManager.default.removeItem(at: url.deletingLastPathComponent()) } let store = SecureKeyStore(vaultURL: url) try store.saveKeys(["openai": "sk-test"]) var blob = try Data(contentsOf: url) blob[blob.count - 1] ^= 0xFF // flip a tag byte try blob.write(to: url) #expect(throws: SecureKeyStore.VaultError.self) { _ = try store.loadKeys() } } @Test func vaultIsMachineBound() throws { let url = temporaryVaultURL() defer { try? FileManager.default.removeItem(at: url.deletingLastPathComponent()) } let machineA = SecureKeyStore(vaultURL: url, machineEntropy: { Data("machine-A".utf8) }) try machineA.saveKeys(["openai": "sk-test"]) let machineB = SecureKeyStore(vaultURL: url, machineEntropy: { Data("machine-B".utf8) }) #expect(throws: SecureKeyStore.VaultError.self) { _ = try machineB.loadKeys() } } @Test func saltIsStableAcrossSaves() throws { let url = temporaryVaultURL() defer { try? FileManager.default.removeItem(at: url.deletingLastPathComponent()) } let store = SecureKeyStore(vaultURL: url) try store.saveKeys(["a": "1"]) let salt1 = try Data(contentsOf: url).prefix(32) try store.saveKeys(["a": "1", "b": "2"]) let salt2 = try Data(contentsOf: url).prefix(32) #expect(salt1 == salt2) #expect(try store.loadKeys() == ["a": "1", "b": "2"]) } @Test func redactionShowsOnlyLastFour() { #expect(SecureKeyStore.redacted("sk-proj-abcdefgh1234") == "••••1234") } }