Policies
Generated from core/api/router.go. Edit the router, not this file.
| Method | Path | Who can call it |
|---|---|---|
GET | /api/v1/policies | Any authenticated user |
POST | /api/v1/policies | Operator, admin |
GET | /api/v1/policies/:id | Any authenticated user |
PUT | /api/v1/policies/:id | Operator, admin |
DELETE | /api/v1/policies/:id | Admin |
Implemented rule types:
rule_type | rule_config |
|---|---|
key_size | {"min_key_size": 2048} — applies to RSA |
max_lifetime | {"max_days": 90} |
ca_restriction | {"allowed_providers": ["acme", "vault"]} |
severity is INFO, WARNING, or BLOCK. Only BLOCK refuses the request; the rest are returned in the issuance response.
domain_pattern scopes a policy — * matches everything, *.example.com matches any subdomain. A policy applies when any requested domain matches.
key_type,naming, andapproval_requiredare accepted by the schema but not implemented, so policies using them currently do nothing. Policy is evaluated on issuance only, not on renewal.
Endpoint detail
GET /api/v1/policies
| Who can call it | Any authenticated user |
| Handler | policyHandler.List |
| Display token | Readable by an unattended screen |
Responses
| Status | Body |
|---|---|
200 | An object with data (Policy[]), total |
500 | { "error": … } |
Example request
curl -X GET 'https://certpilot.example.com/api/v1/policies' \
-H 'Authorization: Bearer <token>'POST /api/v1/policies
| Who can call it | Operator, admin |
| Handler | policyHandler.Create |
| Display token | Refused — not a viewer-safe GET |
Request body
PolicyInput is what a caller may set on a policy. Narrow rather than binding store.Policy, which is what both handlers used to do. That accepted id, created_by, created_at and updated_at from the request body — so a caller could choose a policy's identifier and assert when it was written, and Create handed whatever arrived straight to the store. The binding tags carry the CHECK constraints that migration 001 put on this table. Without them an unknown rule_type reaches PostgreSQL and comes back as a raw SQLSTATE 23514, which tells an operator nothing about which of six values they should have sent.
| Field | Type | Description | |
|---|---|---|---|
name | string | required | |
description | string | ||
is_enabled | boolean | IsEnabled is a pointer so that omitting it leaves the column's default of true, rather than a Go zero value quietly creating every policy disabled. | |
rule_type | string | required | one of key_size, key_type, ca_restriction, max_lifetime, naming, approval_required |
rule_config | string | required | |
domain_pattern | string | ||
severity | string | one of INFO, WARNING, BLOCK |
Responses
| Status | Body |
|---|---|
201 | Created |
400 | { "error": … } |
500 | { "error": … } |
Example request
curl -X POST 'https://certpilot.example.com/api/v1/policies' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"name": "<name>",
"rule_type": "<rule_type>",
"rule_config": "<rule_config>",
"description": "<description>",
"is_enabled": false
}'GET /api/v1/policies/:id
| Who can call it | Any authenticated user |
| Handler | policyHandler.Get |
| Display token | Readable by an unattended screen |
Parameters
| Name | In | Default | |
|---|---|---|---|
id | path | required |
Responses
| Status | Body |
|---|---|
200 | A Policy object |
404 | { "error": … } |
Example request
curl -X GET 'https://certpilot.example.com/api/v1/policies/<id>' \
-H 'Authorization: Bearer <token>'PUT /api/v1/policies/:id
| Who can call it | Operator, admin |
| Handler | policyHandler.Update |
| Display token | Refused — not a viewer-safe GET |
Parameters
| Name | In | Default | |
|---|---|---|---|
id | path | required |
Request body
PolicyInput is what a caller may set on a policy. Narrow rather than binding store.Policy, which is what both handlers used to do. That accepted id, created_by, created_at and updated_at from the request body — so a caller could choose a policy's identifier and assert when it was written, and Create handed whatever arrived straight to the store. The binding tags carry the CHECK constraints that migration 001 put on this table. Without them an unknown rule_type reaches PostgreSQL and comes back as a raw SQLSTATE 23514, which tells an operator nothing about which of six values they should have sent.
| Field | Type | Description | |
|---|---|---|---|
name | string | required | |
description | string | ||
is_enabled | boolean | IsEnabled is a pointer so that omitting it leaves the column's default of true, rather than a Go zero value quietly creating every policy disabled. | |
rule_type | string | required | one of key_size, key_type, ca_restriction, max_lifetime, naming, approval_required |
rule_config | string | required | |
domain_pattern | string | ||
severity | string | one of INFO, WARNING, BLOCK |
Responses
| Status | Body |
|---|---|
200 | Success |
400 | { "error": … } |
500 | { "error": … } |
Example request
curl -X PUT 'https://certpilot.example.com/api/v1/policies/<id>' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"name": "<name>",
"rule_type": "<rule_type>",
"rule_config": "<rule_config>",
"description": "<description>",
"is_enabled": false
}'DELETE /api/v1/policies/:id
| Who can call it | Admin |
| Handler | policyHandler.Delete |
| Display token | Refused — not a viewer-safe GET |
Parameters
| Name | In | Default | |
|---|---|---|---|
id | path | required |
Responses
| Status | Body |
|---|---|
200 | An object with message (string) |
500 | { "error": … } |
Example request
curl -X DELETE 'https://certpilot.example.com/api/v1/policies/<id>' \
-H 'Authorization: Bearer <token>'