PasskeyBase

Zig SDK

The passkeybase package provides a Zig client for the PasskeyBase Management API. Manage users, credentials, apps, roles, and enrollment tokens from your Zig backend.


Installation

Fetch the package and add it to your build configuration:

Terminal
zig fetch --save git+https://github.com/passkeybase/passkeybase-zig
build.zig.zon
# build.zig.zon
.{
    .dependencies = .{
        .passkeybase = .{
            .url = "git+https://github.com/passkeybase/passkeybase-zig",
        },
    },
}
build.zig
# build.zig
const passkeybase = b.dependency("passkeybase", .{});
exe.root_module.addImport("passkeybase", passkeybase.module("passkeybase"));

Quick Start

Initialize the client with your Management API key and tenant domain, then make your first API call.

main.zig
const std = @import("std");
const passkeybase = @import("passkeybase");

pub fn main() !void {
    var client = try passkeybase.Client.init(.{
        .api_key = "YOUR_MANAGEMENT_API_KEY",
        .domain = "myapp.auth.ing",
        .allocator = std.heap.page_allocator,
    });
    defer client.deinit();

    // List all users
    const users = try client.users().list(.{});
    defer users.deinit();

    for (users.data) |user| {
        std.debug.print("{s}: {s}\n", .{ user.id, user.display_name });
    }
}

User Management

Create User

Create a user
const user = try client.users().create(.{
    .external_id = "user_123",
    .display_name = "Jane Doe",
});
defer user.deinit();
std.debug.print("Created user: {s}\n", .{user.id});

List Users

List users with pagination
// List with pagination
const users = try client.users().list(.{
    .page = 1,
    .per_page = 20,
});
defer users.deinit();

for (users.data) |user| {
    std.debug.print("{s}: {s}\n", .{ user.id, user.display_name });
}

std.debug.print("Total: {d}\n", .{users.pagination.total});

Get User

Get a user by ID
const user = try client.users().get("usr_abc123");
defer user.deinit();
std.debug.print("Name: {s}\n", .{user.display_name});
std.debug.print("Passkeys: {d}\n", .{user.passkey_count});
std.debug.print("Last login: {s}\n", .{user.last_login_at});

Update User

Update a user
const user = try client.users().update("usr_abc123", .{
    .display_name = "Jane Smith",
});
defer user.deinit();
std.debug.print("Updated: {s}\n", .{user.display_name});

Delete User

Deletes a user and all their associated passkeys.

Delete a user
try client.users().delete("usr_abc123");

Block / Unblock User

Block and unblock
// Block a user (prevents authentication)
try client.users().block("usr_abc123");

// Unblock a user
try client.users().unblock("usr_abc123");

Credential Management

List Credentials

List all passkey credentials for a specific user.

List credentials
const credentials = try client.credentials().list("usr_abc123");
defer credentials.deinit();

for (credentials.data) |cred| {
    std.debug.print("{s}: {s} ({s})\n", .{
        cred.id, cred.device_name, cred.authenticator_type,
    });
}

Delete Credential

Revoke a specific passkey credential.

Delete a credential
try client.credentials().delete("usr_abc123", "pk_xyz789");

Client / App Management

Create App

Create an OAuth app
const app = try client.apps().create(.{
    .name = "My Mobile App",
    .redirect_uris = &.{"myapp://callback"},
});
defer app.deinit();
std.debug.print("Client ID: {s}\n", .{app.id});

Rotate Secret

Rotate client secret
const secret = try client.apps().rotateSecret("pk_live_abc123");
defer secret.deinit();
std.debug.print("New secret: {s}\n", .{secret.client_secret});

Role Management

Create Role

Create a role
const role = try client.roles().create(.{
    .name = "admin",
    .description = "Administrator role",
});
defer role.deinit();
std.debug.print("Role ID: {s}\n", .{role.id});

Assign Users

Assign users to a role
try client.roles().assignUser("role_abc123", "usr_abc123");

// List users in a role
const users = try client.roles().listUsers("role_abc123");
defer users.deinit();

for (users.data) |user| {
    std.debug.print("{s}: {s}\n", .{ user.id, user.display_name });
}

Enrollment Tokens

Generate a one-time token for enrolling a passkey for an existing user. See the Enrollment guide for the full flow.

Create enrollment token
const token = try client.enrollmentTokens().create(.{
    .external_id = "user_123",
    .display_name = "Jane Doe",
    .expires_in = 3600,
});
defer token.deinit();
std.debug.print("Token: {s}\n", .{token.token});
std.debug.print("Expires: {s}\n", .{token.expires_at});

// Return this token to your frontend for passkey enrollment

Error Handling

API errors are returned as Zig error union types. Use if/elseor switch to handle specific error cases.

Error handling
const std = @import("std");
const passkeybase = @import("passkeybase");

var client = try passkeybase.Client.init(.{
    .api_key = "YOUR_MANAGEMENT_API_KEY",
    .domain = "myapp.auth.ing",
    .allocator = std.heap.page_allocator,
});
defer client.deinit();

const result = client.users().get("usr_nonexistent");
if (result) |user| {
    defer user.deinit();
    std.debug.print("Found: {s}\n", .{user.display_name});
} else |err| switch (err) {
    passkeybase.Error.NotFound => {
        std.debug.print("User not found\n", .{});
    },
    passkeybase.Error.Unauthorized => {
        std.debug.print("Invalid API key\n", .{});
    },
    passkeybase.Error.NetworkError => {
        std.debug.print("Network error\n", .{});
    },
    else => {
        std.debug.print("Unexpected error\n", .{});
    },
}

Configuration Options

Configuration
var client = try passkeybase.Client.init(.{
    .api_key = "YOUR_MANAGEMENT_API_KEY",        // Required. Management API key.
    .domain = "myapp.auth.ing",                  // Required. Your tenant domain.
    .allocator = std.heap.page_allocator,         // Required. Memory allocator.
    .timeout_ms = 30_000,                        // Optional. Request timeout in ms. Default: 10_000.
    .max_retries = 3,                            // Optional. Max retry attempts. Default: 2.
    .base_url = "https://custom.url",            // Optional. Override API base URL.
});
defer client.deinit();
OptionTypeRequiredDescription
api_key[]const u8YesYour Management API key from the dashboard.
domain[]const u8YesYour tenant domain (e.g., myapp.auth.ing).
allocatorstd.mem.AllocatorYesMemory allocator for HTTP and JSON parsing.
timeout_msu32NoRequest timeout in milliseconds. Default: 10_000.
max_retriesu32NoMaximum retry attempts. Default: 2.
base_url[]const u8NoOverride the API base URL.