From fc12174cadda5ea48b655c0354d3237f052a5fce Mon Sep 17 00:00:00 2001 From: Carlos Monastyrski Date: Thu, 11 Dec 2025 17:25:35 -0300 Subject: [PATCH] Add certificate agent documentation and fix issuance endpoint reference --- .infisicalignore | 3 +- .../certificates/create-certificate.mdx | 4 + docs/docs.json | 2 + .../platform/pki/certificates.mdx | 55 ++- .../platform/pki/enrollment-methods/api.mdx | 74 +-- .../platforms/certificate-agent.mdx | 421 ++++++++++++++++++ 6 files changed, 504 insertions(+), 55 deletions(-) create mode 100644 docs/api-reference/endpoints/certificates/create-certificate.mdx create mode 100644 docs/integrations/platforms/certificate-agent.mdx diff --git a/.infisicalignore b/.infisicalignore index 441031b338..46e38aa23f 100644 --- a/.infisicalignore +++ b/.infisicalignore @@ -58,4 +58,5 @@ docs/documentation/platform/pki/enrollment-methods/api.mdx:private-key:139 docs/documentation/platform/pki/certificate-syncs/aws-secrets-manager.mdx:private-key:62 docs/documentation/platform/pki/certificate-syncs/chef.mdx:private-key:61 backend/src/services/certificate-request/certificate-request-service.test.ts:private-key:246 -backend/src/services/certificate-request/certificate-request-service.test.ts:private-key:248 \ No newline at end of file +backend/src/services/certificate-request/certificate-request-service.test.ts:private-key:248 +docs/documentation/platform/pki/enrollment-methods/api.mdx:private-key:142 \ No newline at end of file diff --git a/docs/api-reference/endpoints/certificates/create-certificate.mdx b/docs/api-reference/endpoints/certificates/create-certificate.mdx new file mode 100644 index 0000000000..54b70c4641 --- /dev/null +++ b/docs/api-reference/endpoints/certificates/create-certificate.mdx @@ -0,0 +1,4 @@ +--- +title: "Issue Certificate" +openapi: "POST /api/v1/cert-manager/certificates" +--- diff --git a/docs/docs.json b/docs/docs.json index 39ebf31a94..e3b7296872 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -702,6 +702,7 @@ { "group": "Infrastructure Integrations", "pages": [ + "integrations/platforms/certificate-agent", "documentation/platform/pki/k8s-cert-manager", "documentation/platform/pki/integration-guides/gloo-mesh", "documentation/platform/pki/integration-guides/windows-server-acme", @@ -2520,6 +2521,7 @@ "pages": [ "api-reference/endpoints/certificates/list", "api-reference/endpoints/certificates/read", + "api-reference/endpoints/certificates/create-certificate", "api-reference/endpoints/certificates/renew", "api-reference/endpoints/certificates/update-config", "api-reference/endpoints/certificates/revoke", diff --git a/docs/documentation/platform/pki/certificates.mdx b/docs/documentation/platform/pki/certificates.mdx index da73de37df..0dec4826bd 100644 --- a/docs/documentation/platform/pki/certificates.mdx +++ b/docs/documentation/platform/pki/certificates.mdx @@ -215,20 +215,22 @@ In the following steps, we explore how to issue a X.509 certificate under a CA. - To create a certificate under the certificate template, make an API request to the [Issue Certificate](/api-reference/endpoints/certificates/issue-certificate) API endpoint, + To create a certificate under the certificate template, make an API request to the [Issue Certificate](/api-reference/endpoints/certificates/create-certificate) API endpoint, specifying the issuing CA. - + ### Sample request ```bash Request - curl --location --request POST 'https://app.infisical.com/api/v1/cert-manager/certificates/issue-certificate' \ + curl --location --request POST 'https://app.infisical.com/api/v1/cert-manager/certificates' \ --header 'Content-Type: application/json' \ --data-raw '{ "profileId": "", - "commonName": "service.acme.com", - "ttl": "1y", - "signatureAlgorithm": "RSA-SHA256", - "keyAlgorithm": "RSA_2048" + "attributes": { + "commonName": "service.acme.com", + "ttl": "1y", + "signatureAlgorithm": "RSA-SHA256", + "keyAlgorithm": "RSA_2048" + } }' ``` @@ -236,11 +238,15 @@ In the following steps, we explore how to issue a X.509 certificate under a CA. ```bash Response { - certificate: "...", - certificateChain: "...", - issuingCaCertificate: "...", - privateKey: "...", - serialNumber: "..." + "certificate": { + "certificate": "...", + "certificateChain": "...", + "issuingCaCertificate": "...", + "privateKey": "...", + "serialNumber": "...", + "certificateId": "..." + }, + "certificateRequestId": "..." } ``` @@ -255,17 +261,19 @@ In the following steps, we explore how to issue a X.509 certificate under a CA. Make sure to store the `privateKey` as it is only returned once here at the time of certificate issuance. The `certificate` and `certificateChain` will remain accessible and can be retrieved at any time. - If you have an external private key, you can also create a certificate by making an API request containing a pem-encoded CSR (Certificate Signing Request) to the [Sign Certificate](/api-reference/endpoints/certificates/sign-certificate) API endpoint, specifying the issuing CA. + If you have an external private key, you can also create a certificate by making an API request containing a pem-encoded CSR (Certificate Signing Request) to the same [Issue Certificate](/api-reference/endpoints/certificates/create-certificate) API endpoint. ### Sample request ```bash Request - curl --location --request POST 'https://app.infisical.com/api/v1/cert-manager/certificates/sign-certificate' \ + curl --location --request POST 'https://app.infisical.com/api/v1/cert-manager/certificates' \ --header 'Content-Type: application/json' \ --data-raw '{ - "certificateTemplateId": "", - "csr": "...", - "ttl": "1y", + "profileId": "", + "csr": "-----BEGIN CERTIFICATE REQUEST-----\nMIICvDCCAaQCAQAwdzELMAkGA1UEBhMCVVMxDTALBgNVBAgMBE9oaW8...\n-----END CERTIFICATE REQUEST-----", + "attributes": { + "ttl": "1y" + } }' ``` @@ -273,11 +281,14 @@ In the following steps, we explore how to issue a X.509 certificate under a CA. ```bash Response { - certificate: "...", - certificateChain: "...", - issuingCaCertificate: "...", - privateKey: "...", - serialNumber: "..." + "certificate": { + "certificate": "...", + "certificateChain": "...", + "issuingCaCertificate": "...", + "serialNumber": "...", + "certificateId": "..." + }, + "certificateRequestId": "..." } ``` diff --git a/docs/documentation/platform/pki/enrollment-methods/api.mdx b/docs/documentation/platform/pki/enrollment-methods/api.mdx index bfbac7f2e1..cf0cdb08fc 100644 --- a/docs/documentation/platform/pki/enrollment-methods/api.mdx +++ b/docs/documentation/platform/pki/enrollment-methods/api.mdx @@ -100,32 +100,34 @@ Here, select the certificate profile from step 1 that will be used to issue the - To issue a certificate against the certificate profile, make an API request to the [Issue Certificate](/api-reference/endpoints/certificates/issue-certificate) API endpoint. + To issue a certificate against the certificate profile, make an API request to the [Issue Certificate](/api-reference/endpoints/certificates/create-certificate) API endpoint. ### Sample request ```bash Request - curl --location --request POST 'https://app.infisical.com/api/v1/cert-manager/certificates/issue-certificate' \ + curl --location --request POST 'https://app.infisical.com/api/v1/cert-manager/certificates' \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data-raw '{ "profileId": "", - "commonName": "service.acme.com", - "ttl": "1y", - "signatureAlgorithm": "RSA-SHA256", - "keyAlgorithm": "RSA_2048", - "keyUsages": ["digital_signature", "key_encipherment"], - "extendedKeyUsages": ["server_auth"], - "altNames": [ - { - "type": "DNS", - "value": "service.acme.com" - }, - { - "type": "DNS", - "value": "www.service.acme.com" - } - ] + "attributes": { + "commonName": "service.acme.com", + "ttl": "1y", + "signatureAlgorithm": "RSA-SHA256", + "keyAlgorithm": "RSA_2048", + "keyUsages": ["digital_signature", "key_encipherment"], + "extendedKeyUsages": ["server_auth"], + "altNames": [ + { + "type": "DNS", + "value": "service.acme.com" + }, + { + "type": "DNS", + "value": "www.service.acme.com" + } + ] + } }' ``` @@ -133,12 +135,15 @@ Here, select the certificate profile from step 1 that will be used to issue the ```bash Response { - "certificate": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", - "certificateChain": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", - "issuingCaCertificate": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", - "privateKey": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC...\n-----END PRIVATE KEY-----", - "serialNumber": "123456789012345678", - "certificateId": "880h3456-e29b-41d4-a716-446655440003" + "certificate": { + "certificate": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", + "certificateChain": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", + "issuingCaCertificate": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", + "privateKey": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC...\n-----END PRIVATE KEY-----", + "serialNumber": "123456789012345678", + "certificateId": "880h3456-e29b-41d4-a716-446655440003" + }, + "certificateRequestId": "..." } ``` @@ -146,18 +151,20 @@ Here, select the certificate profile from step 1 that will be used to issue the Make sure to store the `privateKey` as it is only returned once here at the time of certificate issuance. The `certificate` and `certificateChain` will remain accessible and can be retrieved at any time. - If you have an external private key, you can also issue a certificate by making an API request containing a pem-encoded CSR (Certificate Signing Request) to the [Sign Certificate](/api-reference/endpoints/certificates/sign-certificate) API endpoint. + If you have an external private key, you can also issue a certificate by making an API request containing a pem-encoded CSR (Certificate Signing Request) to the same [Issue Certificate](/api-reference/endpoints/certificates/create-certificate) API endpoint. ### Sample request ```bash Request - curl --location --request POST 'https://app.infisical.com/api/v1/cert-manager/certificates/sign-certificate' \ + curl --location --request POST 'https://app.infisical.com/api/v1/cert-manager/certificates' \ --header 'Authorization: Bearer ' \ --header 'Content-Type: application/json' \ --data-raw '{ "profileId": "", "csr": "-----BEGIN CERTIFICATE REQUEST-----\nMIICvDCCAaQCAQAwdzELMAkGA1UEBhMCVVMxDTALBgNVBAgMBE9oaW8...\n-----END CERTIFICATE REQUEST-----", - "ttl": "1y" + "attributes": { + "ttl": "1y" + } }' ``` @@ -165,11 +172,14 @@ Here, select the certificate profile from step 1 that will be used to issue the ```bash Response { - "certificate": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", - "certificateChain": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", - "issuingCaCertificate": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", - "serialNumber": "123456789012345679", - "certificateId": "990i4567-e29b-41d4-a716-446655440004" + "certificate": { + "certificate": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", + "certificateChain": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", + "issuingCaCertificate": "-----BEGIN CERTIFICATE-----\nMIIEpDCCAowCCQD...\n-----END CERTIFICATE-----", + "serialNumber": "123456789012345679", + "certificateId": "990i4567-e29b-41d4-a716-446655440004" + }, + "certificateRequestId": "..." } ``` diff --git a/docs/integrations/platforms/certificate-agent.mdx b/docs/integrations/platforms/certificate-agent.mdx new file mode 100644 index 0000000000..5c1156ec91 --- /dev/null +++ b/docs/integrations/platforms/certificate-agent.mdx @@ -0,0 +1,421 @@ +--- +title: "Infisical Certificate Agent" +description: "Learn how to use Infisical CLI Agent to manage certificates automatically." +--- + +The Infisical Certificate Agent is a specialized feature of the Infisical CLI designed to automatically manage certificates from your Infisical instance. It operates as a daemon process that continuously monitors and handles certificate lifecycle events including issuance, renewal, and storage without manual intervention. + +## Key features + +- **Automated Certificate Management**: Automatically issue, monitor, and renew certificates from Infisical [Certificate Profiles](/documentation/platform/pki/certificates/profiles) +- **Certificate Signing Request (CSR) Support**: Submit pre-generated CSRs for certificate issuance +- **Intelligent Renewal**: Configurable renewal thresholds and automatic certificate renewal before expiration +- **Post-Event Hooks**: Execute custom commands after certificate issuance, renewal, or failure events +- **Multiple Authentication Methods**: Support for Universal Auth, Kubernetes, AWS, GCP, and Azure authentication + +## Getting Started + +To use the Certificate Agent, you'll need: + +1. **Infisical CLI installed**: Download from [GitHub releases](https://github.com/Infisical/cli/releases) +2. **Certificate Profile configured**: Set up a [certificate profile](/documentation/platform/pki/certificates/profiles) in your Infisical project +3. **Authentication credentials**: [Machine identity](/documentation/platform/identities/overview) with appropriate permissions + +The agent operates using a YAML configuration file that defines authentication, certificate profiles, and operational parameters. When started, it authenticates with Infisical and begins monitoring certificates according to your configuration. + +## Certificate Management + +### Manual Certificate Issuance + +The agent will issue a certificate with specified parameters: + +```yaml +version: v1 + +certificates: + - profile-id: "prof-web-server-12345" + common-name: "api.company.com" + alt-names: + - "www.api.company.com" + - "api-v2.company.com" + key-algorithm: "RSA_2048" + signature-algorithm: "RSA-SHA256" + key-usages: + - "digital_signature" + - "key_encipherment" + extended-key-usages: + - "server_auth" + ttl: "30d" + file-output: + private-key-path: "./certs/api/private.key" + certificate-path: "./certs/api/certificate.crt" + file-permissions: "0600" +``` + +### CSR-based Issuance + +Submit a pre-generated [Certificate Signing Request](/documentation/platform/pki/certificates#guide-to-issuing-certificates): + +```yaml +version: v1 + +certificates: + - profile-id: "prof-external-ca-12345" + csr-path: "/etc/ssl/requests/api.csr" + file-output: + certificate-path: "/etc/ssl/certs/api.crt" + ca-certificate-path: "/etc/ssl/certs/ca.crt" + file-permissions: "0644" +``` + +## Lifecycle Management + +The Certificate Agent provides comprehensive certificate lifecycle management with configurable monitoring and renewal: + +```yaml +version: v1 + +certificates: + - profile-id: "prof-web-server-12345" + common-name: "web.company.com" + alt-names: ["www.company.com"] + ttl: "90d" + lifecycle: + renew-before-expiry: "14d" # Renew 14 days before expiration + status-check-interval: "6h" # Check certificate status every 6 hours + file-output: + private-key-path: "./certs/web/private.key" + certificate-path: "./certs/web/certificate.crt" + file-permissions: "0600" + post-hooks: + on-issuance: + command: "systemctl reload nginx" + timeout: 30 + on-renewal: + command: "systemctl reload nginx && logger 'Certificate renewed'" + timeout: 30 +``` + +## Post-Event Hooks + +Execute custom commands in response to certificate lifecycle events using the `post-hooks` configuration: + + + + Runs when a new certificate is successfully issued: + + ```yaml + post-hooks: + on-issuance: + command: | + echo "New certificate issued for ${CERT_COMMON_NAME}" + chown nginx:nginx ${CERT_FILE_PATH} + chmod 644 ${CERT_FILE_PATH} + systemctl reload nginx + timeout: 30 + ``` + + + + Runs when a certificate is successfully renewed: + + ```yaml + post-hooks: + on-renewal: + command: | + echo "Certificate renewed for ${CERT_COMMON_NAME}" + # Reload services that use the certificate + systemctl reload nginx + systemctl reload haproxy + + # Send notification + curl -X POST https://hooks.slack.com/... \ + -d "{'text': 'Certificate for ${CERT_COMMON_NAME} renewed successfully'}" + timeout: 60 + ``` + + + + Runs when certificate operations fail: + + ```yaml + post-hooks: + on-failure: + command: | + echo "Certificate operation failed for ${CERT_COMMON_NAME}: ${ERROR_MESSAGE}" + # Send alert + mail -s "Certificate Failure Alert" admin@company.com < /dev/null + # Log to syslog + logger -p daemon.error "Certificate agent failure: ${ERROR_MESSAGE}" + timeout: 30 + ``` + + + +## Authentication + +The Certificate Agent uses the same authentication system as the Infisical CLI. Configure authentication in the `auth` section of your configuration file. + + + + The Universal Auth method uses a client ID and secret for authentication. + + + + To create a universal auth machine identity, follow the step by step guide outlined [here](/documentation/platform/identities/universal-auth). + + + Update the agent configuration file with the auth method and credentials: + + ```yaml + auth: + type: "universal-auth" + config: + client-id: "./client-id" # Path to file containing client ID + client-secret: "./client-secret" # Path to file containing client secret + remove-client-secret-on-read: false # Optional: remove secret file after reading + ``` + + You can also provide credentials directly: + + ```yaml + auth: + type: "universal-auth" + config: + client-id: "your-client-id" + client-secret: "your-client-secret" + ``` + + + + + The Kubernetes Auth method is used when running the agent in a Kubernetes environment. + + + + To create a Kubernetes machine identity, follow the step by step guide outlined [here](/documentation/platform/identities/kubernetes-auth). + + + Configure the agent to use Kubernetes service account authentication: + + ```yaml + auth: + type: "kubernetes-auth" + config: + identity-id: "your-kubernetes-identity-id" + service-account-token-path: "/var/run/secrets/kubernetes.io/serviceaccount/token" + ``` + + + + + The Azure Auth method is used when running the agent in an Azure environment. + + + + To create an Azure machine identity, follow the step by step guide outlined [here](/documentation/platform/identities/azure-auth). + + + Configure the agent to use Azure managed identity authentication: + + ```yaml + auth: + type: "azure-auth" + config: + identity-id: "your-azure-identity-id" + ``` + + + + + The Native GCP ID Token method is used to authenticate with Infisical when running in a GCP environment. + + + + To create a GCP machine identity, follow the step by step guide outlined [here](/documentation/platform/identities/gcp-auth). + + + Update the agent configuration file with the specified auth method and identity ID: + + ```yaml + auth: + type: "gcp-id-token" + config: + identity-id: "your-gcp-identity-id" + ``` + + + + + + The GCP IAM method is used to authenticate with Infisical with a GCP service account key. + + + + To create a GCP machine identity, follow the step by step guide outlined [here](/documentation/platform/identities/gcp-auth). + + + Update the agent configuration file with the specified auth method, identity ID, and service account key: + + ```yaml + auth: + type: "gcp-iam" + config: + identity-id: "your-gcp-identity-id" + service-account-key: "/path/to/service-account-key.json" + ``` + + + + + + The AWS IAM method is used to authenticate with Infisical with an AWS IAM role while running in an AWS environment. + + + + To create an AWS machine identity, follow the step by step guide outlined [here](/documentation/platform/identities/aws-auth). + + + Update the agent configuration file with the specified auth method and identity ID: + + ```yaml + auth: + type: "aws-iam" + config: + identity-id: "your-aws-identity-id" + ``` + + + + + + +## Retrying mechanism + +The Certificate Agent will automatically attempt to retry failed API requests such as authentication, certificate issuance, and renewal operations. +By default, the agent will retry up to 3 times with a base delay of 200ms and a maximum delay of 5s. + +You can configure the retrying mechanism through the agent configuration file: + +```yaml +infisical: + address: "https://app.infisical.com" + retry-strategy: + max-retries: 3 + max-delay: "5s" + base-delay: "200ms" + +# ... rest of the agent configuration file +``` + +#### Certificate Configuration Parameters + +| Parameter | Description | +| ------------------------------------------------- | ---------------------------------------------------------------------------- | +| `profile-id` | [Certificate profile](/documentation/platform/pki/certificates/profiles) identifier | +| `common-name` | Certificate common name | +| `alt-names` | List of alternative names | +| `ttl` | Certificate validity period | +| `key-algorithm` | Private key algorithm (RSA_2048, RSA_4096, ECDSA_P256, ECDSA_P384) | +| `signature-algorithm` | Signature algorithm (RSA-SHA256, RSA-SHA512, ECDSA-SHA256) | +| `key-usages` | List of key usage values | +| `extended-key-usages` | List of extended key usage values | +| `csr-path` | Path to CSR file | +| `file-output.private-key-path` | Where to store private key | +| `file-output.certificate-path` | Where to store certificate | +| `file-output.ca-certificate-path` | Where to store CA certificate | +| `file-output.file-permissions` | File permissions for generated files | +| `lifecycle.renew-before-expiry` | When to renew before expiration | +| `lifecycle.status-check-interval` | How often to check certificate status | | +| `post-hooks.on-issuance.command` | Command to run on certificate issuance | +| `post-hooks.on-issuance.timeout` | Timeout for issuance command | +| `post-hooks.on-renewal.command` | Command to run on certificate renewal | +| `post-hooks.on-renewal.timeout` | Timeout for renewal command | +| `post-hooks.on-failure.command` | Command to run on operation failure | +| `post-hooks.on-failure.timeout` | Timeout for failure command | + +## Agent configuration file + +The Certificate Agent configuration file is a YAML file that defines how the agent should behave. It includes authentication settings, certificate profiles, and operational parameters. + +Below is a comprehensive example of a Certificate Agent configuration file: + +```yaml example-cert-agent-config.yaml +version: v1 + +# Required: Infisical server configuration +infisical: + address: "https://app.infisical.com" + retry-strategy: + max-retries: 3 + max-delay: "5s" + base-delay: "200ms" + +# Authentication configuration +auth: + type: "universal-auth" + config: + client-id: "your-client-id" + client-secret: "your-client-secret" + +certificates: + - profile-id: "prof-web-server-12345" + common-name: "web.company.com" + alt-names: ["web.company.com", "www.company.com"] + ttl: "90d" + key-algorithm: "RSA_2048" + signature-algorithm: "RSA-SHA256" + key-usages: + - "digital_signature" + - "key_encipherment" + extended-key-usages: + - "server_auth" + + # Lifecycle management + lifecycle: + renew-before-expiry: "30d" + status-check-interval: "6h" + max-failure-retries: 3 + failure-retry-interval: "1h" + + # File output configuration + file-output: + private-key-path: "/etc/ssl/private/web.key" + certificate-path: "/etc/ssl/certs/web.crt" + ca-certificate-path: "/etc/ssl/certs/ca.crt" + file-permissions: "0600" + + # Post-event hooks + post-hooks: + on-issuance: + command: | + echo "Certificate issued for ${CERT_COMMON_NAME}" + systemctl reload nginx + timeout: 30 + + on-renewal: + command: | + echo "Certificate renewed for ${CERT_COMMON_NAME}" + systemctl reload nginx + timeout: 30 + + on-failure: + command: | + echo "Certificate operation failed: ${ERROR_MESSAGE}" + mail -s "Certificate Alert" admin@company.com < /dev/null + timeout: 30 +``` + +After defining the agent configuration file, run the command below pointing to the path where the agent configuration file is located. + +```bash +infisical cert-manager agent --config /path/to/your/agent-config.yaml +``` + +The agent will start as a daemon process, continuously monitoring and managing certificates according to your configuration. You can also run it in the foreground for debugging: + +```bash +infisical cert-manager agent --config /path/to/your/agent-config.yaml --verbose +``` + +For production deployments, consider running the agent as a system service to ensure it starts automatically and runs continuously.