Skip to main content

API Keys

API keys let you automate cert-ctrl without interactive sessions. They are scoped to a user, carry explicit permissions, and authenticate via Authorization: Bearer. Once the server accepts a key, the request inherits the key owner's permissions.

Important: API keys are bearer secrets. Treat them like passwords. Store them securely, rotate them regularly, and delete keys you no longer need.

1. Create a key

Most users create keys in the web console. You can also create keys via the REST API.

Request

POST /apiv1/me/apikeys

{
"name": "ci-bot",
"expires_in_seconds": 86400,
"permissions": [
{"obtype": "certificates", "obid": "123", "actions": ["read", "issue"]},
{"obtype": "devices", "obid": "*", "actions": ["read"]}
]
}

Notes

  • expires_in_seconds is required.
  • The response includes a token field only once. Save it immediately.
  • Permission scopes are listed at GET /apiv1/permissions/catalog.
  • ACME account scope name is acme_accounts (underscore).

2. Permissions model

Each permission entry contains:

  • obtype: scope name (e.g., certificates, devices, acme_accounts)
  • obid: * or a concrete object id
  • actions: allowed actions (e.g., read, write, issue)

For install-config automation, the scope is ForInstallConfigUpdate with action update.

3. Certificate-focused permission recipes

This document intentionally focuses on certificate issuance and distribution. Below are practical permission sets to use when creating an API key.

A) Issue/renew + download/export one certificate

Use a concrete certificate id (recommended):

{
"name": "cert-issuer",
"expires_in_seconds": 86400,
"permissions": [
{"obtype": "certificates", "obid": "123", "actions": ["read", "issue"]}
]
}

What it enables:

  • GET /apiv1/me/certificates/123
  • POST /apiv1/me/certificates/123/issues
  • GET /apiv1/me/certificates/123/issues/history
  • GET /apiv1/me/certificates/123/export

B) Assign one certificate to devices

POST /apiv1/me/certificate-assign derives the certificate id from the API key’s permissions. For this endpoint you must provide a concrete certificate id (not *).

{
"name": "cert-assigner",
"expires_in_seconds": 86400,
"permissions": [
{"obtype": "certificates", "obid": "123", "actions": ["read"]}
]
}

C) List devices (optional)

If your automation needs to discover devices via API:

{
"name": "device-reader",
"expires_in_seconds": 86400,
"permissions": [
{"obtype": "devices", "obid": "*", "actions": ["read"]}
]
}

D) Update install-config (optional)

If your automation uses POST /apiv1/me/install-config-update/:device_public_id, add:

{"obtype": "ForInstallConfigUpdate", "obid": "*", "actions": ["update"]}

4. Authenticating requests

REST / JSON clients

curl -H "Authorization: Bearer ak_yourtoken" \
https://cjj365.cc/apiv1/me/certificates

5. Common automation flows

Assign a certificate to a device (API key only)

POST /apiv1/me/certificate-assign uses the certificate id from the API key permission (certificates + read). The payload includes only the device public id.

curl -X POST https://cjj365.cc/apiv1/me/certificate-assign \
-H "Authorization: Bearer ak_yourtoken" \
-H "Content-Type: application/json" \
-d '{"device_public_id":"dev_abc123"}'

Update a device install-config (API key only)

POST /apiv1/me/install-config-update/:device_public_id requires ForInstallConfigUpdate permission.

curl -X POST https://cjj365.cc/apiv1/me/install-config-update/dev_abc123 \
-H "Authorization: Bearer ak_yourtoken" \
-H "Content-Type: application/json" \
-d '{"patches":[{"ob_type":"cert","ob_id":10,"enabled":true}]}'

Best practices

  • Least privilege: create separate keys per integration with tailored scopes.
  • Short-lived keys: keep lifetimes tight and rotate automatically.
  • Monitoring: audit usage and revoke keys you no longer need.

Troubleshooting

Common error codes when using API keys:

CodeMeaningFix
5003Not foundVerify the resource exists and belongs to the API key owner.
5022ForbiddenThe API key lacks required permission(s) for this action.
5018UnauthorizedMissing/invalid token, or API key expired/revoked.
5000Invalid argumentCheck request JSON fields and types.

If authentication fails you may see api key lacks required permissions or invalid token in the error message.