domainchief

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 12, 2026 License: MIT Imports: 16 Imported by: 0

README

Domain Chief for libdns

Go Reference

This package implements the libdns interfaces for Domain Chief hosted DNS, allowing you to manage DNS records and solve ACME DNS-01 challenges.

Configuration

import "github.com/libdns/domainchief"

provider := &domainchief.Provider{
	APIToken: "ctt_...",
}
Field JSON Description
APIToken api_token A Domain Chief API token (required).
BaseURL base_url Overrides the API base URL, defaults to https://domain.chief.app/api/v1.
HTTPClient - Overrides the HTTP client used for API requests.

The zone is the domain name in Domain Chief, for example example.com.. The domain must use hosted DNS.

API token scopes

Create an API token in your Chief Tools account for the team that owns your domains. The scopes it needs depend on how you use the provider:

Use Scope
ACME DNS-01 challenges only domainchief:acme:write
Reading DNS records domainchief:dns:read
Reading and changing any DNS record domainchief:dns:write
ListZones domainchief:domains:read

A write scope includes the matching read scope, so domainchief:dns:write also allows reading records.

The domainchief:acme:write scope only allows publishing and deleting TXT records on _acme-challenge names. It cannot read your domains or change any other record, so it is the recommended scope when you only need certificates. Anyone holding the token can still complete DNS-01 challenges and obtain certificates for the domains in your team, so treat it as a secret.

Behavior

  • AppendRecords and DeleteRecords send TXT records on _acme-challenge names holding an ACME challenge value (base64url characters) to the dedicated ACME challenge endpoints. Those keep other values on the same name, so concurrent challenges for the same name (for example example.com and *.example.com) work. Challenge values that are not deleted are removed automatically after 24 hours. Because the challenge endpoint does not report whether a value existed, DeleteRecords always returns challenge records as deleted.
  • All other records use the DNS record endpoints.
  • Supported record types are A, AAAA, ALIAS, CAA, CNAME, MX, NS, SRV, TLSA and TXT. ALIAS and TLSA records are returned as libdns.RR.
  • TTLs are rounded to the closest TTL Domain Chief supports (60, 300, 900, 1800, 3600, 21600, 43200, 86400, 172800, 259200, 604800, 1209600 or 2592000 seconds). A TTL of 0 uses 3600 seconds.
  • SetRecords is not atomic. For every name and type in the input it keeps records with the same value, updates other existing records to hold the remaining values and deletes leftover records. When an error is returned some of the changes may have been applied.
  • Requests are retried for a few seconds when another hosted DNS write for the same domain is still running or when the API is rate limiting requests.
  • DNS changes are published to the hosted DNS nameservers asynchronously. They are usually visible within a minute.

Testing

The unit tests run against a local fake API:

go test ./...

The integration test changes records in a real zone. It needs a token with the domainchief:acme:write and domainchief:dns:write scopes:

DOMAINCHIEF_API_TOKEN=ctt_... DOMAINCHIEF_TEST_ZONE=example.com. go test -run TestIntegration -v ./...

The shared libdns test suite runs from the libdnstest directory with the same environment variables.

Documentation

Overview

Package domainchief implements a DNS record management client compatible with the libdns interfaces for Domain Chief (https://domain.chief.app) hosted DNS.

TXT records on `_acme-challenge` names holding an ACME challenge value are published and removed through the dedicated ACME challenge endpoints, so solving ACME DNS-01 challenges only requires an API token with the `domainchief:acme:write` scope. All other operations use the DNS record endpoints: reading records requires the `domainchief:dns:read` scope and changing them requires the `domainchief:dns:write` scope, which includes `domainchief:dns:read`. ListZones requires the `domainchief:domains:read` scope.

Index

Constants

View Source
const DefaultBaseURL = "https://domain.chief.app/api/v1"

DefaultBaseURL is the base URL of the Domain Chief API.

Variables

This section is empty.

Functions

This section is empty.

Types

type APIError

type APIError struct {
	// StatusCode is the HTTP status code of the response.
	StatusCode int

	// Code is the machine readable error code, if the API returned one (for example `dns.not_hosted`).
	Code string

	// Message is the human readable error message, including validation errors.
	Message string
}

APIError is returned when the Domain Chief API responds with an unexpected status code.

func (*APIError) Error

func (e *APIError) Error() string

Error implements the error interface.

type Provider

type Provider struct {
	// APIToken is a Domain Chief API token. Create one at https://account.chief.app/team/select/token/create.
	//
	// For ACME DNS-01 challenges only the `domainchief:acme:write` scope is needed.
	APIToken string `json:"api_token,omitempty"`

	// BaseURL overrides the Domain Chief API base URL, defaults to DefaultBaseURL.
	BaseURL string `json:"base_url,omitempty"`

	// HTTPClient overrides the HTTP client used for API requests.
	HTTPClient *http.Client `json:"-"`
	// contains filtered or unexported fields
}

Provider facilitates DNS record manipulation with Domain Chief hosted DNS.

The zone passed to the methods is the domain name in Domain Chief, for example `example.com.`. The domain must use hosted DNS.

func (*Provider) AppendRecords

func (p *Provider) AppendRecords(ctx context.Context, zone string, records []libdns.Record) ([]libdns.Record, error)

AppendRecords adds records to the zone. It returns the records that were added.

ACME challenge TXT records on `_acme-challenge` names are published through the ACME challenge endpoint, which keeps other values on the same name and returns the existing record when the value is already published.

func (*Provider) DeleteRecords

func (p *Provider) DeleteRecords(ctx context.Context, zone string, records []libdns.Record) ([]libdns.Record, error)

DeleteRecords deletes the specified records from the zone. It returns the records that were deleted.

ACME challenge TXT records on `_acme-challenge` names with a value are removed through the ACME challenge endpoint. That endpoint does not report whether the value existed, so the input record is always returned.

func (*Provider) GetRecords

func (p *Provider) GetRecords(ctx context.Context, zone string) ([]libdns.Record, error)

GetRecords lists all the records in the zone.

Record types without a libdns struct type (ALIAS and TLSA) are returned as libdns.RR.

func (*Provider) ListZones

func (p *Provider) ListZones(ctx context.Context) ([]libdns.Zone, error)

ListZones returns the domains in the team that use hosted DNS.

func (*Provider) SetRecords

func (p *Provider) SetRecords(ctx context.Context, zone string, records []libdns.Record) ([]libdns.Record, error)

SetRecords sets the records in the zone, either by updating existing records or creating new ones. It returns the records that were set.

For every (name, type) pair in the input, existing records with the same value are kept, other existing records are updated to hold the remaining values and leftover records are deleted. This is not atomic, when an error is returned some of the changes may have been applied.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL