fetch_ml/cli/src/security.zig
Jeremie Fraeys 1147958e15
feat: enhance CLI with improved commands and WebSocket handling
- Refactor command structure for better organization
- Improve WebSocket client frame handling
- Add response handler improvements
- Update queue, requeue, and status commands
- Add security module for CLI authentication
2026-02-16 20:38:08 -05:00

59 lines
1.8 KiB
Zig

const std = @import("std");
/// Secure credential storage using macOS Keychain
pub const SecureStorage = struct {
const ServiceName = "com.fetchml.cli";
/// Store API key in macOS Keychain
pub fn storeApiKey(api_key: []const u8) !void {
const result = std.process.Child.run(.{
.allocator = std.heap.page_allocator,
.argv = &.{
"security", "add-generic-password",
"-s", ServiceName,
"-a", "api_key",
"-w", api_key,
"-U",
},
}) catch return error.KeychainError;
if (result.term.Exited != 0) {
return error.KeychainError;
}
}
/// Retrieve API key from macOS Keychain
pub fn retrieveApiKey(allocator: std.mem.Allocator) !?[]u8 {
const result = std.process.Child.run(.{
.allocator = allocator,
.argv = &.{
"security", "find-generic-password",
"-s", ServiceName,
"-a", "api_key",
"-w",
},
}) catch return null;
if (result.term.Exited != 0) {
return null;
}
const stdout = result.stdout;
if (stdout.len > 0 and stdout[stdout.len - 1] == '\n') {
return try allocator.dupe(u8, stdout[0 .. stdout.len - 1]);
}
return try allocator.dupe(u8, stdout);
}
/// Delete stored API key
pub fn deleteApiKey() void {
_ = std.process.Child.run(.{
.allocator = std.heap.page_allocator,
.argv = &.{
"security", "delete-generic-password",
"-s", ServiceName,
"-a", "api_key",
},
}) catch {};
}
};