Skip to content

Add SharingId for the X-Gandi-Sharing-Id header#15

Open
bjorn wants to merge 1 commit intolibdns:masterfrom
bjorn:sharing-id-header
Open

Add SharingId for the X-Gandi-Sharing-Id header#15
bjorn wants to merge 1 commit intolibdns:masterfrom
bjorn:sharing-id-header

Conversation

@bjorn
Copy link
Copy Markdown

@bjorn bjorn commented May 5, 2026

When the PAT user's default organization is not the one that owns the domain, list endpoints still find the domain (Gandi filters by all visible orgs) but per-record-set endpoints return 404. Sending X-Gandi-Sharing-Id with the org UUID makes Gandi resolve into that org's context and the lookups work.

Setting Provider.SharingId injects the header on every API call. The default empty value preserves existing behaviour.

bjorn added a commit to bjorn/caddy-dns-gandi that referenced this pull request May 5, 2026
Sets Provider.SharingId on the underlying libdns/gandi provider,
which sends X-Gandi-Sharing-Id on every API call. Required when the
PAT user's default organization isn't the one that owns the domain;
without it Gandi 404s on per-record-set endpoints.

Drive-by while in the same parser: the existing block-form
`bearer_token <value>` branch read d.Val() before advancing past the
directive name, so it stored the literal string "bearer_token" in
BearerToken and then tripped d.NextArg() on the actual value,
returning a "wrong argument count" error. Same fix applied here for
sharing_id.

Depends on libdns/gandi#15 (which adds the SharingId field). Once
that lands, bump the libdns/gandi require accordingly.
When the PAT user's default organization is not the one that owns
the domain, list endpoints still find the domain (Gandi filters by
all visible orgs) but per-record-set endpoints return 404. Sending
X-Gandi-Sharing-Id with the org UUID makes Gandi resolve into that
org's context and the lookups work.

Setting Provider.SharingId injects the header on every API call.
The default empty value preserves existing behaviour.
@bjorn bjorn force-pushed the sharing-id-header branch from 797b2af to 37d82ec Compare May 5, 2026 07:33
@bjorn
Copy link
Copy Markdown
Author

bjorn commented May 5, 2026

Heads-up: the X-Gandi-Sharing-Id header form seems undocumented.

The Gandi API reference at https://api.gandi.net/docs/reference/#Sharing-ID documents sharing_id only as a query string parameter, not as a header. Empirically the two forms have different reach:

  • ?sharing_id=<uuid> works on collection endpoints (GET /v5/livedns/domains returns the right list).
  • X-Gandi-Sharing-Id: <uuid> works on both collection and per-record-set endpoints (GET /v5/livedns/domains/<fqdn>/records).

The query-parameter form was the first thing I tried, but it 404s on the per-record-set endpoints, which is exactly where this provider needs to operate. The header form makes those endpoints succeed. Tested with two different PATs (full-permission and product-scoped) on the same domain.

Reproducer:

PAT=<your-pat>; ORG=<owner-org-uuid>; FQDN=<your-domain>

# query parameter: works on list, 404 on records
curl -sI -H "Authorization: Bearer $PAT" \
  "https://api.gandi.net/v5/livedns/domains/$FQDN/records?sharing_id=$ORG" | head -1

# header: works on records
curl -sI -H "Authorization: Bearer $PAT" -H "X-Gandi-Sharing-Id: $ORG" \
  "https://api.gandi.net/v5/livedns/domains/$FQDN/records" | head -1

Since I couldn't find the header form documented, I want to flag this explicitly: the PR relies on undocumented but empirically working behaviour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant