jedisct1/zig-common-access-token
Zig implementation of Common Access Token (CTA-5007).
A Zig implementation of the Common Access Token (CAT) specification with HMAC signatures.
Common Access Token (CAT) is a token format designed for authorization and authentication in distributed systems, particularly for media and content delivery applications. It provides a secure, compact, and efficient way to represent claims and authorization information between parties.
CAT is built on established standards:
This library provides a complete implementation for generating and validating Common Access Tokens (CAT) using HMAC signatures. It is designed to be interoperable with other implementations like node-cat and common-access-token.
Key benefits of using CAT tokens:
Token Operations:
Claims Support:
CBOR Implementation:
Error Handling:
Integration:
Add this library to your build.zig.zon
file:
.dependencies = .{
.zig_cat = .{
.url = "https://github.com/yourusername/zig-cat/archive/refs/tags/v0.1.0.tar.gz",
.hash = "...",
},
},
Then in your build.zig
:
const zig_cat = b.dependency("zig_cat", .{
.target = target,
.optimize = optimize,
});
exe.addModule("cat", zig_cat.module("cat"));
This example demonstrates how to create a CAT token with standard claims:
const std = @import("std");
const cat = @import("cat");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
// Create a key for token signing
const key_hex = "403697de87af64611c1d32a05dab0fe1fcb715a86ab435f1ec99192d79569388";
const key = try cat.util.hexToBytes(allocator, key_hex);
defer allocator.free(key);
// Create a map of keys
var keys = std.StringHashMap([]const u8).init(allocator);
defer keys.deinit();
try keys.put("Symmetric256", key);
// Create CAT options
const cat_options = cat.CatOptions{
.keys = keys,
.expect_cwt_tag = true,
};
// Create a CAT instance
var cat_instance = cat.Cat.init(allocator, cat_options);
defer cat_instance.deinit();
// Create claims
var claims = cat.Claims.init(allocator);
defer claims.deinit();
try claims.setIssuer("example");
try claims.setSubject("user123");
try claims.setAudience("service");
const now = cat.util.currentTimeSecs();
try claims.setExpiration(now + 120); // 2 minutes from now
try claims.setIssuedAt(now);
// Generate token
const token = try cat_instance.generate(claims, .{
.validation_type = cat.CatValidationType.Mac,
.alg = "HS256",
.kid = "Symmetric256",
.generate_cwt_id = true,
});
defer allocator.free(token);
std.debug.print("Generated token: {s}\n", .{token});
}
const std = @import("std");
const cat = @import("cat");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
// Create a key for token validation
const key_hex = "403697de87af64611c1d32a05dab0fe1fcb715a86ab435f1ec99192d79569388";
const key = try cat.util.hexToBytes(allocator, key_hex);
defer allocator.free(key);
// Create a map of keys
var keys = std.StringHashMap([]const u8).init(allocator);
defer keys.deinit();
try keys.put("Symmetric256", key);
// Create CAT options
const cat_options = cat.CatOptions{
.keys = keys,
.expect_cwt_tag = true,
};
// Create a CAT instance
var cat_instance = cat.Cat.init(allocator, cat_options);
defer cat_instance.deinit();
// Validate the token
var claims = try cat_instance.validate(token, cat.CatValidationType.Mac, .{
.issuer = "example",
.audience = null,
});
defer claims.deinit();
std.debug.print("Token is valid!\n", .{});
}
The library includes several ready-to-use examples in the examples/
directory:
To run an example:
# Generate a token
zig build generate
# Validate a token (replace <token> with an actual token)
zig build validate -- <token>
# Test interoperability with NodeJS implementation
zig build interop [-- <token>]
# Use CAT-specific claims
zig build cat_claims
When using CAT tokens in your applications, keep these security best practices in mind:
Key Management:
Token Validation:
Token Lifetime:
Claims:
This library is designed to be interoperable with other CAT implementations:
This project is licensed under the MIT License - see the LICENSE file for details.