Skip to content

Commit b89f33c

Browse files
committed
chore(release): publish public TLS API docs update
- refresh storefront docs from the latest console OpenAPI spec - add TLS organization and staged certificate completion endpoints - update OV and certbro workflows for public hdl_* org IDs - align generated examples with the current org_id completion flow certbro-public-snapshot: true certbro-private-commit: 803112ad6d7417d86c211e44f1684816cd1b9fdf certbro-private-branch: main
1 parent 9de1440 commit b89f33c

16 files changed

Lines changed: 292 additions & 111 deletions

README.de.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ sudo certbro issue \
5959
--webserver nginx
6060
```
6161

62-
Für DV-Produkte wartet `certbro issue` in der Regel auf die Ausstellung und deployt das Zertifikat direkt. Für OV- oder Business-Produkte kann die TLS API stattdessen `action_required=true` mit einer `completion_url` unter `/my/certs/...` zurückgeben. In diesem Fall speichert `certbro` das Pending-Material lokal, gibt die Console-URL aus und endet erfolgreich. Ein späterer Lauf von `certbro renew` setzt denselben offenen Vorgang fort, nachdem der Console-Schritt abgeschlossen wurde.
62+
Für DV-Produkte wartet `certbro issue` in der Regel auf die Ausstellung und deployt das Zertifikat direkt. Für OV- oder organisationsvalidierte Business-Produkte kann die TLS API stattdessen `action_required=true` mit einer `completion_url` unter `/my/certs/...` zurückgeben. In diesem Fall speichert `certbro` das Pending-Material lokal, gibt die Console-URL aus und endet erfolgreich. Ein späterer Lauf von `certbro renew` setzt denselben offenen Vorgang fort, nachdem der Console-Schritt abgeschlossen wurde.
6363

6464
Renewals manuell ausführen:
6565

@@ -78,7 +78,7 @@ sudo certbro install
7878
- Multi-Domain-Zertifikate: `--dns-name` für jede SAN wiederholen
7979
- Paralleler RSA- und ECDSA-Betrieb: `certbro issue-pair`
8080
- Bereits bestehende regfish-Bestellungen: Import per `certificate_id`
81-
- OV- oder Business-Bestellungen: `certbro issue` kann eine Console-`completion_url` zurückgeben; wenn bereits eine nutzbare `--org-id` bekannt ist, direkt mitgeben, andernfalls die Bestellung dort abschließen und später mit `certbro renew` finalisieren
81+
- OV- oder Business-Bestellungen: `--org-id` erwartet die öffentliche TLS-Organisations-ID aus `/tls/organization` beziehungsweise `organization_id`, zum Beispiel `hdl_ABCDEFGHJKLMN`; `certbro issue` kann trotzdem noch eine Console-`completion_url` zurückgeben, wenn die Organisation nicht bestellbar ist oder weitere Completion-Daten fehlen
8282
- Sofortiger Ersatz: `certbro renew --name example-com --force`
8383
- Einmaliger Laufzeit-Override: `certbro renew --name example-com --force --validity-days 30`
8484
- Pending-Ausstellung nach Timeout: `certbro renew --name example-com` erneut ausführen, um denselben Request weiter zu beobachten

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ sudo certbro issue \
5959
--webserver nginx
6060
```
6161

62-
For DV products, `certbro issue` usually waits for issuance and deploys the certificate directly. For OV or business products, the TLS API can instead return `action_required=true` with a `completion_url` under `/my/certs/...`. In that case, `certbro` stores the pending material locally, prints the Console URL, and exits successfully. A later `certbro renew` run resumes the same pending order after the Console step has been completed.
62+
For DV products, `certbro issue` usually waits for issuance and deploys the certificate directly. For OV or organization-validated business products, the TLS API can instead return `action_required=true` with a `completion_url` under `/my/certs/...`. In that case, `certbro` stores the pending material locally, prints the Console URL, and exits successfully. A later `certbro renew` run resumes the same pending order after the Console step has been completed.
6363

6464
Run renewals manually:
6565

@@ -78,7 +78,7 @@ sudo certbro install
7878
- Multi-domain certificates: repeat `--dns-name` for each SAN
7979
- Dual RSA and ECDSA deployment: use `certbro issue-pair`
8080
- Existing regfish orders: import by `certificate_id`
81-
- OV or business orders: `certbro issue` can return a Console `completion_url`; if you already know a usable `--org-id`, pass it up front, otherwise complete the order there and let `certbro renew` finish it later
81+
- OV or business orders: `--org-id` expects the public TLS organization id from `/tls/organization` or `organization_id`, for example `hdl_ABCDEFGHJKLMN`; `certbro issue` can still return a Console `completion_url` if the organization is not yet usable or more completion data is required
8282
- Immediate replacement: `certbro renew --name example-com --force`
8383
- One-off renewal lifetime override: `certbro renew --name example-com --force --validity-days 30`
8484
- Pending issuance after a timeout: rerun `certbro renew --name example-com` to resume monitoring the existing request

docs/de/issuing-certificates.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,18 @@ sudo certbro issue \
2929
--product SecureSite
3030
```
3131

32-
Wenn bereits eine nutzbare Organisations-ID aus der regfish Console bekannt ist, kann sie direkt mitgegeben werden:
32+
Wenn bereits eine nutzbare öffentliche TLS-Organisations-ID bekannt ist, kann sie direkt mitgegeben werden:
3333

3434
```sh
3535
sudo certbro issue \
3636
--name example-com \
3737
--common-name example.com \
3838
--product SecureSite \
39-
--org-id 42
39+
--org-id hdl_ABCDEFGHJKLMN
4040
```
4141

42+
`--org-id` erwartet dieselbe öffentliche `org_id`, die die TLS API in `/tls/organization`, `organization_id` und `POST /tls/certificate/{certificate_id}/complete` verwendet. Es geht nicht um eine interne numerische Datenbank-ID.
43+
4244
Damit wird die Bestellung direkt mit der vorhandenen Organisation verknüpft. Ist diese Organisation bereits bestellbar, kann die TLS API ohne gestufte Completion-URL direkt weiterlaufen.
4345

4446
Wenn die TLS API mit `action_required=true` antwortet, gibt `certbro` unter anderem diese Felder aus:
@@ -47,6 +49,7 @@ Wenn die TLS API mit `action_required=true` antwortet, gibt `certbro` unter ande
4749
- `pending_reason`
4850
- `pending_message`
4951
- `completion_url`
52+
- `organization_id`
5053

5154
Die `completion_url` in der regfish Console öffnen, die OV-/Business-Bestellung dort abschließen und danach erneut ausführen:
5255

@@ -56,6 +59,16 @@ sudo certbro renew --name example-com
5659

5760
`certbro renew` setzt denselben offenen Vorgang fort und provisioniert DCV, sobald die Validierungsrecords verfügbar sind. Wenn das Zertifikat danach schon bereitsteht, lädt `certbro` es im selben Lauf herunter und deployt es. Wenn die providerseitige OV-/Business-Validierung noch läuft, beendet sich `certbro renew` sauber und setzt den Vorgang bei einem späteren Renewal-Lauf oder Timer-Zyklus fort.
5861

62+
Für direkte API-Clients beschreibt die aktuelle OpenAPI-Spezifikation zusätzlich den programmatischen Abschluss über `POST /tls/certificate/{certificate_id}/complete` mit einem Body wie:
63+
64+
```json
65+
{
66+
"org_id": "hdl_ABCDEFGHJKLMN"
67+
}
68+
```
69+
70+
`certbro` selbst nutzt dafür weiterhin die Console-`completion_url` und übernimmt danach im `renew`-Pfad wieder DCV, Polling, Download und Deployment.
71+
5972
## Laufzeit-Zeitplan
6073

6174
`certbro` folgt dem CA/B-Forum-Zeitplan für öffentlich vertrauenswürdige TLS-Zertifikate und beginnt aus Sicherheitsgründen jeweils einen Tag früher mit dem niedrigeren Default.

docs/de/workflow-overview.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,24 @@ sudo certbro issue \
6363
--name example-com \
6464
--common-name example.com \
6565
--product SecureSite \
66-
--org-id 42
66+
--org-id hdl_ABCDEFGHJKLMN
6767
```
6868

6969
Dadurch ändert sich der Ablauf:
7070

7171
1. `certbro` erzeugt Private Key und CSR weiterhin lokal.
72-
2. Die Bestellung wird direkt mit der vorhandenen Organisations-ID verknüpft.
72+
2. Die Bestellung wird direkt mit der vorhandenen öffentlichen TLS-Organisations-ID (`org_id`, zum Beispiel `hdl_ABCDEFGHJKLMN`) verknüpft.
7373
3. Ist diese Organisation bereits bestellbar, kann die TLS API ohne den gestuften `completion_url`-Zwischenschritt direkt weiterlaufen.
7474
4. Dann nähert sich der Ablauf wieder dem DV-Fall an: Validierungsrecords können schon in der ersten `issue`-Antwort auftauchen, und `certbro issue` kann die DNS-Records direkt im selben Lauf anlegen.
7575
5. Ist die Organisation unvollständig oder nicht bestellbar, kann die TLS API trotzdem wieder in den gestuften OV-/Business-Flow zurückfallen.
7676

77+
Wichtig für API und CLI:
78+
79+
- `POST /tls/certificate` nimmt optional `org_id`.
80+
- `POST /tls/certificate/{certificate_id}/complete` verlangt `org_id` zwingend.
81+
- Die Response-Felder `organization_id` und `organization.id` verwenden dieselbe öffentliche string-basierte TLS-Organisations-ID.
82+
- Ältere numerische Beispiele sind dafür nicht mehr maßgeblich.
83+
7784
## Was `renew` bei Pending-Bestellungen macht
7885

7986
`certbro renew` ist der einzige Resume- und Finalize-Mechanismus für offene Bestellungen.

docs/en/issuing-certificates.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,18 @@ sudo certbro issue \
2929
--product SecureSite
3030
```
3131

32-
If you already know a usable organization id from the regfish Console, pass it up front:
32+
If you already know a usable public TLS organization id, pass it up front:
3333

3434
```sh
3535
sudo certbro issue \
3636
--name example-com \
3737
--common-name example.com \
3838
--product SecureSite \
39-
--org-id 42
39+
--org-id hdl_ABCDEFGHJKLMN
4040
```
4141

42+
`--org-id` expects the same public `org_id` used by the TLS API in `/tls/organization`, `organization_id`, and `POST /tls/certificate/{certificate_id}/complete`. It is not an internal numeric database id.
43+
4244
That pre-links the order to the existing organization. If the organization is already usable for ordering, the TLS API can continue directly without returning a staged completion URL.
4345

4446
If the TLS API responds with `action_required=true`, `certbro` prints fields such as:
@@ -47,6 +49,7 @@ If the TLS API responds with `action_required=true`, `certbro` prints fields suc
4749
- `pending_reason`
4850
- `pending_message`
4951
- `completion_url`
52+
- `organization_id`
5053

5154
Follow the `completion_url` in the regfish Console, complete the OV/business order there, and then rerun:
5255

@@ -56,6 +59,16 @@ sudo certbro renew --name example-com
5659

5760
`certbro renew` resumes the same pending order and provisions DCV as soon as validation records become available. If the certificate is already ready afterwards, `certbro` downloads and deploys it in the same run. If provider-side OV/business validation is still pending, `certbro renew` exits cleanly and continues on a later renewal run or timer cycle.
5861

62+
For direct API clients, the current OpenAPI specification also documents programmatic completion via `POST /tls/certificate/{certificate_id}/complete` with a payload such as:
63+
64+
```json
65+
{
66+
"org_id": "hdl_ABCDEFGHJKLMN"
67+
}
68+
```
69+
70+
`certbro` itself still relies on the Console `completion_url` for that human completion step and then resumes DCV, polling, download, and deployment during `renew`.
71+
5972
## Validity Schedule
6073

6174
`certbro` follows the CA/B Forum schedule for publicly trusted TLS certificate lifetimes and starts using the upcoming lower default one day earlier as a safety margin.

docs/en/workflow-overview.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,24 @@ sudo certbro issue \
6363
--name example-com \
6464
--common-name example.com \
6565
--product SecureSite \
66-
--org-id 42
66+
--org-id hdl_ABCDEFGHJKLMN
6767
```
6868

6969
This changes the flow:
7070

7171
1. `certbro` still creates the private key and CSR locally.
72-
2. The order is pre-linked to the existing organization id.
72+
2. The order is pre-linked to the existing public TLS organization id (`org_id`, for example `hdl_ABCDEFGHJKLMN`).
7373
3. If that organization is already usable for ordering, the TLS API can continue directly without the staged `completion_url` detour.
7474
4. In that case, the flow moves closer to DV behavior: validation records can appear immediately in the initial `issue` response, and `certbro issue` can provision DNS in the same run.
7575
5. If the organization is incomplete or unusable, the TLS API can still fall back to the staged OV/business flow above.
7676

77+
Important for both API and CLI consumers:
78+
79+
- `POST /tls/certificate` accepts optional `org_id`.
80+
- `POST /tls/certificate/{certificate_id}/complete` requires `org_id`.
81+
- The response fields `organization_id` and `organization.id` use the same public string-based TLS organization id.
82+
- Older numeric examples are no longer authoritative for this flow.
83+
7784
## What `renew` Does for Pending Orders
7885

7986
`certbro renew` is the only resume and finalize mechanism for pending orders.

internal/api/client.go

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import (
1414
"net/http"
1515
"strings"
1616
"time"
17+
18+
"github.com/regfish/certbro/internal/tlsmeta"
1719
)
1820

1921
// DefaultBaseURL is the default regfish API endpoint used by certbro.
@@ -113,30 +115,30 @@ type TLSCertificateReissue struct {
113115

114116
// TLSOrganizationSummary contains the minimal organization metadata returned with a certificate.
115117
type TLSOrganizationSummary struct {
116-
ID int `json:"id"`
117-
Name string `json:"name"`
118-
Status string `json:"status"`
119-
UsableForOrdering bool `json:"usable_for_ordering"`
118+
ID tlsmeta.OrganizationID `json:"id"`
119+
Name string `json:"name"`
120+
Status string `json:"status"`
121+
UsableForOrdering bool `json:"usable_for_ordering"`
120122
}
121123

122124
// TLSCertificate models the public TLS certificate resource returned by the API.
123125
type TLSCertificate struct {
124-
ID string `json:"id"`
125-
Status string `json:"status"`
126-
CommonName string `json:"common_name"`
127-
Product string `json:"product"`
128-
Provider string `json:"provider"`
129-
DNSNames []string `json:"dns_names"`
130-
OrderState string `json:"order_state,omitempty"`
131-
ActionRequired bool `json:"action_required"`
132-
PendingReason string `json:"pending_reason,omitempty"`
133-
PendingMessage string `json:"pending_message,omitempty"`
134-
CompletionURL string `json:"completion_url,omitempty"`
135-
OrganizationID int `json:"organization_id,omitempty"`
136-
RevocationScope string `json:"revocation_scope,omitempty"`
137-
RevocationPendingScope string `json:"revocation_pending_scope,omitempty"`
138-
RenewalSupported bool `json:"renewal_supported,omitempty"`
139-
ReissueSupported bool `json:"reissue_supported"`
126+
ID string `json:"id"`
127+
Status string `json:"status"`
128+
CommonName string `json:"common_name"`
129+
Product string `json:"product"`
130+
Provider string `json:"provider"`
131+
DNSNames []string `json:"dns_names"`
132+
OrderState string `json:"order_state,omitempty"`
133+
ActionRequired bool `json:"action_required"`
134+
PendingReason string `json:"pending_reason,omitempty"`
135+
PendingMessage string `json:"pending_message,omitempty"`
136+
CompletionURL string `json:"completion_url,omitempty"`
137+
OrganizationID tlsmeta.OrganizationID `json:"organization_id,omitempty"`
138+
RevocationScope string `json:"revocation_scope,omitempty"`
139+
RevocationPendingScope string `json:"revocation_pending_scope,omitempty"`
140+
RenewalSupported bool `json:"renewal_supported,omitempty"`
141+
ReissueSupported bool `json:"reissue_supported"`
140142
// ValidityDays is the purchased base order validity in days. It is not the authoritative
141143
// issued certificate lifetime for provider-linked renewals. Use ValidFrom and ValidUntil
142144
// to determine the effective issued lifetime.
@@ -173,13 +175,13 @@ type TLSProduct struct {
173175

174176
// TLSCertificateRequest is the order or renewal payload for POST /tls/certificate.
175177
type TLSCertificateRequest struct {
176-
SKU string `json:"sku"`
177-
CommonName string `json:"common_name"`
178-
DNSNames []string `json:"dns_names,omitempty"`
179-
CSR string `json:"csr"`
180-
DCVMethod string `json:"dcv_method"`
181-
DCVEmails []string `json:"dcv_emails,omitempty"`
182-
Organization int `json:"org_id,omitempty"`
178+
SKU string `json:"sku"`
179+
CommonName string `json:"common_name"`
180+
DNSNames []string `json:"dns_names,omitempty"`
181+
CSR string `json:"csr"`
182+
DCVMethod string `json:"dcv_method"`
183+
DCVEmails []string `json:"dcv_emails,omitempty"`
184+
Organization tlsmeta.OrganizationID `json:"org_id,omitempty"`
183185
// RenewalOfCertificateID turns a regular order into a provider-linked renewal of an existing
184186
// public certificate id. Any remaining-validity bonus is decided by the provider and is not
185187
// guaranteed until the new certificate has actually been issued.

internal/api/client_test.go

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ func TestGetCertificateParsesCurrentOpenAPIFields(t *testing.T) {
134134
"pending_reason": "validation_pending",
135135
"pending_message": "The TLS certificate order is waiting for domain validation.",
136136
"completion_url": "https://dash.regfish.com/my/certs/7K9QW3M2ZT8HJ/complete",
137-
"organization_id": 42,
137+
"organization_id": "hdl_ABCDEFGHJKLMN",
138138
"revocation_scope": "certificate",
139139
"revocation_pending_scope": "order",
140140
"renewal_supported": true,
@@ -151,7 +151,7 @@ func TestGetCertificateParsesCurrentOpenAPIFields(t *testing.T) {
151151
"order_cancellation_mode": "revoke_issued",
152152
"order_cancellable_until": "2026-03-20T10:00:00Z",
153153
"organization": {
154-
"id": 42,
154+
"id": "hdl_ABCDEFGHJKLMN",
155155
"name": "Example GmbH",
156156
"status": "validated",
157157
"usable_for_ordering": true
@@ -183,7 +183,7 @@ func TestGetCertificateParsesCurrentOpenAPIFields(t *testing.T) {
183183
if cert.ActionRequired {
184184
t.Fatalf("ActionRequired = %v, want false", cert.ActionRequired)
185185
}
186-
if cert.PendingReason != "validation_pending" || cert.OrganizationID != 42 {
186+
if cert.PendingReason != "validation_pending" || cert.OrganizationID != "hdl_ABCDEFGHJKLMN" {
187187
t.Fatalf("pending/org fields = %#v", cert)
188188
}
189189
if cert.CompletionURL != "https://dash.regfish.com/my/certs/7K9QW3M2ZT8HJ/complete" {
@@ -206,3 +206,44 @@ func TestGetCertificateParsesCurrentOpenAPIFields(t *testing.T) {
206206
t.Fatalf("OrderCancellableUntil = %v, want %v", cert.OrderCancellableUntil, wantUntil)
207207
}
208208
}
209+
210+
func TestGetCertificateAcceptsLegacyNumericOrganizationID(t *testing.T) {
211+
server, err := testutil.NewLocalServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
212+
w.Header().Set("Content-Type", "application/json")
213+
_, _ = w.Write([]byte(`{
214+
"success": true,
215+
"response": {
216+
"id": "7K9QW3M2ZT8HJ",
217+
"status": "pending",
218+
"common_name": "example.com",
219+
"product": "SecureSite",
220+
"provider": "digicert",
221+
"dns_names": ["example.com"],
222+
"action_required": true,
223+
"pending_reason": "organization_required",
224+
"pending_message": "Complete the organization and contact validation in the regfish Console.",
225+
"completion_url": "https://dash.regfish.com/my/certs/7K9QW3M2ZT8HJ/complete",
226+
"organization_id": 42,
227+
"certificate_pem_available": false
228+
}
229+
}`))
230+
}))
231+
if err != nil {
232+
t.Fatalf("NewLocalServer() error = %v", err)
233+
}
234+
defer server.Close()
235+
236+
client, err := NewClient("secret", server.URL, "certbro/test")
237+
if err != nil {
238+
t.Fatalf("NewClient() error = %v", err)
239+
}
240+
client.HTTPClient = server.Client()
241+
242+
cert, err := client.GetCertificate(context.Background(), "7K9QW3M2ZT8HJ")
243+
if err != nil {
244+
t.Fatalf("GetCertificate() error = %v", err)
245+
}
246+
if cert.OrganizationID != "42" {
247+
t.Fatalf("cert.OrganizationID = %q, want legacy id converted to string", cert.OrganizationID)
248+
}
249+
}

0 commit comments

Comments
 (0)