For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
GitHub
DocumentationREST API Reference
DocumentationREST API Reference
    • Home
  • Overview
    • What is NICo?
    • Key Capabilities
    • Operational Principles
    • Day 0 / Day 1 / Day 2 Lifecycle
    • Scope and Boundaries
  • Getting Started
    • Building NICo Containers
    • Quick Start Guide
  • Provisioning (Day 0 Operations)
    • Ingesting Hosts
    • Host Validation
    • SKU Validation
  • DPU Management
    • DPU Lifecycle Management
    • DPU Configuration
    • BlueField DPU Operations
  • Architecture
    • Overview and Components
    • Redfish Workflow
    • Redfish Endpoints Reference
    • Reliable State Handling
    • Networking Integrations
    • Health Checks and Health Aggregation
    • Health Probe IDs
    • Health Alert Classifications
    • Key Group Synchronization
  • Operations
    • NVLink Partitioning
    • Release Instance API Enhancements
    • IP Resource Pools
    • BGP Peering
  • Playbooks
    • Azure OIDC for Infra Controller Web UI
    • Force Deleting and Rebuilding Hosts
    • Rebooting a Machine
    • InfiniBand Setup
  • Development
    • Codebase Overview
    • Bootable Artifacts
    • Local Development
    • Running a PXE Client in a VM
    • TLS and SPIFFE Certificates
    • SPIFFE and casbin policies with admin-cli
    • Re-creating Issuer/CA in Local Dev
    • Visual Studio Code Remote Development
    • Adding Support for New Hardware
    • Build Guide
  • Reference
    • Hardware Compatibility List
    • Release Notes
    • FAQs
    • Glossary
GitHub
NVIDIANVIDIA
Developer-friendly docs for your API
Privacy Policy | Manage My Privacy | Do Not Sell or Share My Data | Terms of Service | Accessibility | Corporate Policies | Product Security | Contact

Copyright © 2026, NVIDIA Corporation.

LogoLogo
On this page
  • Building
  • Connecting to carbide-api
  • TLS options
  • Config file
  • Example invocations
  • SOCKS5 proxy support
  • Generating client certificates
  • Creating an admin CA and client cert with OpenSSL
  • Certificate subject fields and how they map to authorization
  • Server-side configuration (carbide-api)
  • TLS section
  • Configuring authorization
  • Casbin policy
  • How principals are identified
  • Writing policy rules
  • Full example: carbide-api config with external admin certs
  • Permissive mode
Development

Carbide Admin CLI

||View as Markdown|
Previous

TLS and SPIFFE Certificates

Next

Re-creating Issuer/CA in Local Dev

carbide-admin-cli is the command-line tool for managing a Carbide site. It communicates with carbide-api over gRPC with mutual TLS (mTLS).

Building

From the repository root:

1# Debug build (faster compile, larger binary)
2cargo build -p carbide-admin-cli
3
4# Release build (optimized, for deployment)
5cargo build -p carbide-admin-cli --release

The binary is written to:

  • target/debug/carbide-admin-cli (debug)
  • target/release/carbide-admin-cli (release)

Connecting to carbide-api

The CLI needs three things to connect:

  1. API URL — where carbide-api is listening
  2. Root CA certificate — to verify the server’s TLS certificate
  3. Client certificate + key — to authenticate this client to the server

TLS options

FlagEnvironment variableConfig file keyDescription
-c / --carbide-apiCARBIDE_API_URLcarbide_api_urlcarbide-api URL
--forge-root-ca-pathFORGE_ROOT_CA_PATHforge_root_ca_pathRoot CA cert (PEM) used to verify the server
--client-cert-pathCLIENT_CERT_PATHclient_cert_pathClient certificate (PEM)
--client-key-pathCLIENT_KEY_PATHclient_key_pathClient private key (PEM)

Config file

Instead of passing flags every time, create $HOME/.config/carbide_api_cli.json:

1{
2 "carbide_api_url": "https://carbide-api.example.com:1079",
3 "forge_root_ca_path": "/etc/carbide/certs/ca.crt",
4 "client_cert_path": "/etc/carbide/certs/client.crt",
5 "client_key_path": "/etc/carbide/certs/client.key"
6}

Example invocations

1# Explicit flags
2carbide-admin-cli \
3 -c https://carbide-api.example.com:1079 \
4 --forge-root-ca-path /etc/carbide/certs/ca.crt \
5 --client-cert-path /etc/carbide/certs/client.crt \
6 --client-key-path /etc/carbide/certs/client.key \
7 version
8
9# With config file (no flags needed)
10carbide-admin-cli version

SOCKS5 proxy support

If the CLI needs to reach carbide-api through a SOCKS5 proxy, set one of: http_proxy, https_proxy, HTTP_PROXY, or HTTPS_PROXY. Only the socks5:// scheme is supported.

Generating client certificates

carbide-api uses mTLS: the server verifies the client’s certificate against a trusted CA.

Creating an admin CA and client cert with OpenSSL

The following creates a self-contained CA and client certificate. In production you would typically use your organization’s existing PKI instead of a self-signed CA.

1# 1. Generate the CA key and self-signed certificate
2openssl ecparam -name prime256v1 -genkey -noout -out admin-ca.key
3openssl req -x509 -new -key admin-ca.key -sha256 -days 3650 \
4 -out admin-ca.crt \
5 -subj "/O=ExampleCo/CN=ExampleCo Carbide Admin CA"
6
7# 2. Generate a client key
8openssl ecparam -name prime256v1 -genkey -noout -out client.key
9
10# 3. Create a CSR with operator identity in the subject
11# - O = organization (matched by required_equals if configured)
12# - OU = group (used for role-based authorization via group_from)
13# - CN = username (used for audit logging via username_from)
14openssl req -new -key client.key -out client.csr \
15 -subj "/O=ExampleCo/OU=site-admins/CN=jdoe"
16
17# 4. Create an extensions file for clientAuth
18cat > client_ext.cnf <<EOF
19basicConstraints = CA:FALSE
20keyUsage = digitalSignature, keyEncipherment
21extendedKeyUsage = clientAuth
22EOF
23
24# 5. Sign the client certificate with the CA
25openssl x509 -req -in client.csr \
26 -CA admin-ca.crt -CAkey admin-ca.key -CAcreateserial \
27 -out client.crt -days 365 -sha256 \
28 -extfile client_ext.cnf
29
30# 6. Clean up intermediate files
31rm -f client.csr client_ext.cnf admin-ca.srl

This produces:

FilePurpose
admin-ca.crtRoot CA — configure as admin_root_cafile_path in carbide-api
admin-ca.keyCA private key — keep offline/secured
client.crtOperator’s client certificate
client.keyOperator’s client private key

Certificate subject fields and how they map to authorization

The [auth.cli_certs] section in carbide-api-config.toml controls how certificate fields are interpreted:

Config keyPurposeExample
required_equalsIssuer/subject fields that must match exactly for the cert to be accepted{ "IssuerO" = "ExampleCo", "IssuerCN" = "ExampleCo Carbide Admin CA" }
group_fromWhich cert field to extract the authorization group from"SubjectOU"
username_fromWhich cert field to extract the username from (for audit trails)"SubjectCN"
usernameFixed username for all certs of this type (alternative to username_from)"shared-admin"

The available CertComponent values are:

  • IssuerO, IssuerOU, IssuerCN — from the certificate issuer
  • SubjectO, SubjectOU, SubjectCN — from the certificate subject

Server-side configuration (carbide-api)

TLS section

The [tls] section of carbide-api-config.toml tells carbide-api where to find its own server certificate and which CAs to trust for client authentication:

1[tls]
2identity_pemfile_path = "/path/to/server.crt"
3identity_keyfile_path = "/path/to/server.key"
4root_cafile_path = "/path/to/internal-ca.crt"
5admin_root_cafile_path = "/path/to/admin-ca.crt"
KeyDescription
identity_pemfile_pathServer’s own TLS certificate (PEM)
identity_keyfile_pathServer’s private key (PEM)
root_cafile_pathCA used to verify internal client certs
admin_root_cafile_pathCA used to verify external admin client certs

carbide-api loads both root_cafile_path and admin_root_cafile_path into its TLS trust store. A client presenting a certificate signed by either CA will pass the TLS handshake.

Configuring authorization

Authorization is configured in the [auth] section of carbide-api-config.toml.

Casbin policy

carbide-api uses Casbin with an RBAC model for authorization. The model is compiled into the binary and uses two rule types:

  • g (grouping) rules — map a principal identifier to a role name
  • p (policy) rules — allow a principal or role to call a gRPC method (glob matching is supported on the method name)

The policy file is a CSV referenced by casbin_policy_file:

1[auth]
2permissive_mode = false
3casbin_policy_file = "/path/to/casbin-policy.csv"
How principals are identified
Certificate typePrincipal identifier formatExample
External admin certexternal-role/<group>external-role/site-admins
Any trusted certtrusted-certificate
No certanonymous

The <group> in external-role/<group> comes from the certificate field specified by group_from in [auth.cli_certs].

Writing policy rules

Sample policy file:

1# On `g` rules: These associate a principal (second column) with a role name
2# (third column). This causes the named role to also be looked up as if it were
3# a principal.
4#
5# On `p` rules: These allow a principal or role (second column) to perform the
6# named action (third column). Glob matching is available on the action field.
7#
8
9
10# Map the carbide-dhcp SPIFFE ID to the carbide-dhcp role.
11# FIXME: verify that this is how these SPIFFE service identifiers look in reality.
12g, spiffe-service-id/carbide-dhcp, carbide-dhcp
13g, spiffe-service-id/carbide-dns, carbide-dns
14g, spiffe-machine-id, machine
15
16# Allow the carbide-dhcp role to call its methods.
17p, carbide-dhcp, forge/DiscoverDhcp
18
19# Same idea for carbide-dns.
20p, carbide-dns, forge/LookupRecord
21
22# Anonymous access to endpoints that don't modify state or expose any customer
23# or site data should be fine.
24p, anonymous, forge/Version
25
26# Allow anonymous access to methods used by machines that may not have their
27# certificates from us yet.
28p, anonymous, forge/DiscoverMachine
29p, anonymous, forge/ReportForgeScoutError
30p, anonymous, forge/AttestQuote
31
32# Allow anonymous access to methods used by dpu-agent. As of 2023-09-28 there
33# are probably a fair amount of agents across the environments that don't have a
34# certificate and are not ready for strict enforcement.
35p, anonymous, forge/FindInstanceByMachineID
36p, anonymous, forge/GetManagedHostNetworkConfig
37p, anonymous, forge/RecordDpuNetworkStatus
38
39# The client cert generated above has OU=site-admins in its subject.
40# With group_from = "SubjectOU" in [auth.cli_certs], that becomes the
41# principal "external-role/site-admins". Map it to a role and grant access.
42g, external-role/site-admins, site-admin
43p, site-admin, forge/*
44
45# Example of a restricted role: a cert with OU=viewers would only get
46# read access to a handful of methods.
47g, external-role/viewers, viewer
48p, viewer, forge/Version
49p, viewer, forge/GetMachine
50p, viewer, forge/ListMachines
51p, viewer, forge/GetInstance
52p, viewer, forge/ListInstances
53
54
55# Allow any certificate we trust to hit any Forge method.
56# FIXME: This should be removed once we have more fine-grained rule coverage.
57p, trusted-certificate, forge/*

The method names in the forge/<Method> column correspond to the gRPC method names defined in the protobuf service definitions. Glob matching (*) is supported.

Full example: carbide-api config with external admin certs
1[tls]
2identity_pemfile_path = "/path/to/server.crt"
3identity_keyfile_path = "/path/to/server.key"
4root_cafile_path = "/path/to/internal-ca.crt"
5admin_root_cafile_path = "/path/to/admin-ca.crt"
6
7[auth]
8permissive_mode = false
9casbin_policy_file = "/path/to/casbin-policy.csv"
10
11[auth.cli_certs]
12required_equals = { "IssuerO" = "ExampleCo", "IssuerCN" = "ExampleCo Carbide Admin CA" }
13group_from = "SubjectOU"
14username_from = "SubjectCN"
15
16[auth.trust]
17spiffe_trust_domain = "forge.local"
18spiffe_service_base_paths = [
19 "/forge-system/sa/",
20 "/default/sa/",
21 "/elektra-site-agent/sa/",
22]
23spiffe_machine_base_path = "/forge-system/machine/"
24additional_issuer_cns = []

With this configuration, a client certificate with subject /O=ExampleCo/OU=site-admins/CN=jdoe and issuer /O=ExampleCo/CN=ExampleCo Carbide Admin CA would:

  1. Pass the required_equals check (IssuerO and IssuerCN match)
  2. Be assigned group site-admins (from SubjectOU)
  3. Be identified as user jdoe (from SubjectCN)
  4. Receive the principal external-role/site-admins
  5. Be authorized according to whatever casbin policy rules match that principal

You can see an example of a complete carbide-api configuration file here

Permissive mode

Setting permissive_mode = true in the [auth] section causes the authorization engine to allow all requests, even when the casbin policy would deny them. Denied requests are logged with a warning instead of being rejected:

1[auth]
2permissive_mode = true

When permissive mode is active, carbide-api logs messages like:

WARN The policy engine denied this request, but --auth-permissive-mode overrides it.

Use permissive mode only for:

  • Initial deployment and bring-up, before certificates are fully configured
  • Debugging authorization issues (enable temporarily, check logs, then disable)
  • Development environments

Do not leave permissive mode enabled in production. It bypasses all authorization checks. Any client that can complete the TLS handshake (or any client at all, if TLS is also disabled) can call any API method.

You can also set permissive mode via environment variable without editing the config file:

1CARBIDE_API_AUTH="{permissive_mode=true}"