Skip to main content

Use the custdctl Client

custdctl is the command line client for Custd. It is a single binary: no Go toolchain, no repository, no runtime to install. It signs in as your tenant administrator and operates your own tenant — the same public contract the released SDK uses.

Before you start​

You need:

  • a Custd tenant you administer, and
  • the client credentials your tenant administrator created for the CLI.

If you do not have a CLI client yet, ask your tenant administrator to create one in Admin → Credentials. Choose the CLI login client purpose: it is a public client with no secret, and the page prints the exact config init command to run. Copy it as it is.

Install the client​

Download the release asset for your platform from the Custd downloads repository, then verify the checksum before you run it.

PlatformAsset
Windows 64-bitcustdctl_<version>_windows_amd64.exe
macOS Apple Siliconcustdctl_<version>_darwin_arm64
Linux 64-bit ARMcustdctl_<version>_linux_arm64
Linux 64-bit x86custdctl_<version>_linux_amd64

Windows​

  1. Download custdctl_<version>_windows_amd64.exe.
  2. Verify it against SHA256SUMS — on Windows: certutil -hashfile custdctl_<version>_windows_amd64.exe SHA256.
  3. Move the binary to a folder on your PATH, for example C:\Program Files\Custd\. Rename it to custdctl.exe if you like; the .exe suffix is the only difference.
  4. Open a new terminal so the new PATH entry is visible.

macOS​

  1. Download custdctl_<version>_darwin_arm64. macOS requires Apple Silicon; Intel Macs are not supported.
  2. Verify it against the published checksum for that one asset: shasum -a 256 custdctl_<version>_darwin_arm64 and compare the value with the matching line in SHA256SUMS.
  3. Move the binary into /usr/local/bin and make it executable: sudo mv custdctl_<version>_darwin_arm64 /usr/local/bin/custdctl && sudo chmod +x /usr/local/bin/custdctl.
  4. If macOS blocks the first run because the binary is not notarised, approve it once in System Settings → Privacy & Security, or clear the quarantine attribute with xattr -d com.apple.quarantine /usr/local/bin/custdctl.

Linux​

  1. Download custdctl_<version>_linux_amd64 (or linux_arm64).
  2. Verify it against the published checksum for that one asset: sha256sum custdctl_<version>_linux_amd64 and compare the value with the matching line in SHA256SUMS.
  3. Move the binary into /usr/local/bin and make it executable: sudo mv custdctl_<version>_linux_amd64 /usr/local/bin/custdctl && sudo chmod +x /usr/local/bin/custdctl.

Check the install at any time:

custdctl version

It prints the build facts of the binary: the version, the commit it was built from, the build time and the Go version. The commit is what identifies a build — quote it in a support message. The same facts appear in custdctl system about --json.

Point the client at your tenant​

Run the config init line your administrator gave you. It carries your API URL, your identity provider issuer, your client id, your audience and your scopes, and the profile name the client will use — which is your client id:

custdctl config init --profile "acme-cli" --api-url "https://custd.com" --issuer-url "https://auth.custd.com/" --client-id "acme-cli" --audience "custd" --scope "openid profile offline_access admin producers.provision"

The issuer must exactly match the server's discovery metadata, including the trailing slash. The public Custd issuer is https://auth.custd.com/. The public API base is https://custd.com, as configured by the production chart.

Copy it as it is. If you would rather set it up yourself, custdctl config init --help lists every flag.

The client stores this profile and the token it obtains on your machine, readable only by your own account:

PlatformLocation
Windows%AppData%\custd\config.yaml and %AppData%\custd\tokens.json
macOS and Linux$XDG_CONFIG_HOME/custd/, or ~/.config/custd/, holding config.yaml and tokens.json

custdctl config path prints the path the client is using.

Sign in​

custdctl login --profile acme-cli

The client opens your browser, you sign in as your tenant administrator, and the browser hands the token back to the client. If no browser opens, the client prints a URL to paste into any browser yourself.

If your machine has no browser — a server, a container, a locked-down desktop — use the device-code flow instead:

custdctl login --profile acme-cli --method device

It prints a code and a URL. Open the URL on any device, enter the code, and the client receives the token.

Check who you are signed in as:

custdctl account

Sign out again with custdctl logout --profile acme-cli.

Find the command you need​

custdctl --help lists every command, grouped into Your tenant and Platform operator. The grouping is the authority the command needs: a command under Platform operator is refused for a tenant administrator.

custdctl commands

prints the same inventory for your tenant, with a description beside every command, so you can search for the verb you want:

custdctl commands | grep -i rotate

Every command explains itself:

custdctl sites rotate-write-key --help
custdctl help sites rotate-write-key

Both print the same block: what the command does, which flags it requires, every flag with a description, and one working example. A wrong flag is reported with the flag that was not understood and the exit code 2.

Get output you can pipe​

Every command that produces data emits exactly one JSON document, so it pipes straight into jq:

custdctl account --json | jq -r '.email'
custdctl usage me --json | jq '.data.rows[] | {meter: .meterSlug, quantity}'

The request identifier travels inside the document, so you can quote it in a support message.

When something goes wrong​

These answer the first questions of any support conversation:

custdctl diagnose
custdctl system about --json
custdctl system diagnostics capture --tenant-scope --output ./custd-evidence

custdctl diagnose is the one that reports reachability: it separates a network problem from an authorization one (api_reachable=true but api_authorized=false means the credential is the problem, not the network). system about --json reports the build the binary was made from. system diagnostics capture --tenant-scope writes a bounded, redacted evidence bundle for your tenant.

The system-wide capture needs platform authority and is refused for a tenant administrator. That refusal is intentional: a tenant cannot read another tenant's state.

Send the two outputs to your Custd contact. The evidence bundle contains no event payloads, no credentials and no other tenant's data.

What the client cannot do​

The client is a thin shell over the same contract your SDK uses. It does not grant authority: a command is refused when your account lacks the role, and the CLI has no way around that. Anything that needs platform authority — operating the platform, running maintenance commands, reading another tenant — is out of scope for a tenant administrator by design.