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/certificate-request.mdx b/docs/api-reference/endpoints/certificates/certificate-request.mdx new file mode 100644 index 0000000000..fcf601f5ed --- /dev/null +++ b/docs/api-reference/endpoints/certificates/certificate-request.mdx @@ -0,0 +1,4 @@ +--- +title: "Get Certificate Request" +openapi: "GET /api/v1/cert-manager/certificates/certificate-requests/{requestId}" +--- 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 e08a2d8e18..94d8152055 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,8 @@ "pages": [ "api-reference/endpoints/certificates/list", "api-reference/endpoints/certificates/read", + "api-reference/endpoints/certificates/certificate-request", + "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 deleted file mode 100644 index da73de37df..0000000000 --- a/docs/documentation/platform/pki/certificates.mdx +++ /dev/null @@ -1,401 +0,0 @@ ---- -title: "Certificates" -sidebarTitle: "Certificates" -description: "Learn how to issue X.509 certificates with Infisical." ---- - -## Concept - -Assuming that you've created a Private CA hierarchy with a root CA and an intermediate CA, you can now issue/revoke X.509 certificates using the intermediate CA. - -
- -```mermaid -graph TD - A[Root CA] - A --> B[Intermediate CA] - A --> C[Intermediate CA] - B --> D[Leaf Certificate] - C --> E[Leaf Certificate] -``` - -
- -## Workflow - -The typical workflow for managing certificates consists of the following steps: - -1. Issuing a certificate under an intermediate CA with details like name and validity period. As part of certificate issuance, you can either issue a certificate directly from a CA or do it via a certificate template. -2. Managing certificate lifecycle events such as certificate renewal and revocation. As part of the certificate revocation flow, - you can also query for a Certificate Revocation List [CRL](https://en.wikipedia.org/wiki/Certificate_revocation_list), a time-stamped, signed - data structure issued by a CA containing a list of revoked certificates to check if a certificate has been revoked. - - - Note that this workflow can be executed via the Infisical UI or manually such - as via API. - - -## Guide to Issuing Certificates - -In the following steps, we explore how to issue a X.509 certificate under a CA. - - - - - - - A certificate template is a set of policies for certificates issued under that template; each template is bound to a specific CA and can also be bound to a certificate collection for alerting such that any certificate issued under the template is automatically added to the collection. - - With certificate templates, you can specify, for example, that issued certificates must have a common name (CN) adhering to a specific format like `.*.acme.com` or perhaps that the max TTL cannot be more than 1 year. - - Head to your Project > Certificate Authorities > Your Issuing CA and create a certificate template. - - ![pki certificate template modal](/images/platform/pki/certificate/cert-template-modal.png) - - Here's some guidance on each field: - - - Template Name: A name for the certificate template. - - Issuing CA: The Certificate Authority (CA) that will issue certificates based on this template. - - Certificate Collection (Optional): The certificate collection that certificates should be added to when issued under the template. - - Common Name (CN): A regular expression used to validate the common name in certificate requests. - - Alternative Names (SANs): A regular expression used to validate subject alternative names in certificate requests. - - TTL: The maximum Time-to-Live (TTL) for certificates issued using this template. - - Key Usage: The key usage constraint or default value for certificates issued using this template. - - Extended Key Usage: The extended key usage constraint or default value for certificates issued using this template. - - - To create a certificate, head to your Project > Internal PKI > Certificates and press **Issue** under the Certificates section. - - ![pki issue certificate](/images/platform/pki/certificate/cert-issue.png) - - Here, set the **Certificate Template** to the template from step 1 and fill out the rest of the details for the certificate to be issued. - - ![pki issue certificate modal](/images/platform/pki/certificate/cert-issue-modal.png) - - Here's some guidance on each field: - - - Friendly Name: A friendly name for the certificate; this is only for display and defaults to the common name of the certificate if left empty. - - Common Name (CN): The common name for the certificate like `service.acme.com`. - - Alternative Names (SANs): A comma-delimited list of Subject Alternative Names (SANs) for the certificate; these can be hostnames or email addresses like `app1.acme.com, app2.acme.com`. - - TTL: The lifetime of the certificate in seconds. - - Key Usage: The key usage extension of the certificate. - - Extended Key Usage: The extended key usage extension of the certificate. - - - Note that Infisical PKI supports issuing certificates without certificate templates as well. If this is desired, then you can set the **Certificate Template** field to **None** - and specify the **Issuing CA** and optional **Certificate Collection** fields; the rest of the fields for the issued certificate remain the same. - - That said, we recommend using certificate templates to enforce policies and attach expiration monitoring on issued certificates. - - - - - Once you have created the certificate from step 1, you'll be presented with the certificate details including the **Certificate Body**, **Certificate Chain**, and **Private Key**. - - ![pki certificate body](/images/platform/pki/certificate/cert-body.png) - - - Make sure to download and store the **Private Key** in a secure location as it will only be displayed once at the time of certificate issuance. - The **Certificate Body** and **Certificate Chain** will remain accessible and can be copied at any time. - - - - - - - - - A certificate template is a set of policies for certificates issued under that template; each template is bound to a specific CA and can also be bound to a certificate collection for alerting such that any certificate issued under the template is automatically added to the collection. - - With certificate templates, you can specify, for example, that issued certificates must have a common name (CN) adhering to a specific format like .*.acme.com or perhaps that the max TTL cannot be more than 1 year. - - To create a certificate template, make an API request to the [Create Certificate Template](/api-reference/endpoints/certificate-templates-v2/create) API endpoint, specifying the issuing CA. - - ### Sample request - - ```bash Request - curl --request POST \ - --url https://us.infisical.com/api/v2/certificate-templates \ - --header 'Content-Type: application/json' \ - --data '{ - "projectId": "", - "name": "", - "description": "", - "subject": [ - { - "type": "common_name", - "allowed": [ - "*.infisical.com" - ] - } - ], - "sans": [ - { - "type": "dns_name", - "allowed": [ - "*.sample.com" - ] - } - ], - "keyUsages": { - "allowed": [ - "digital_signature" - ] - }, - "extendedKeyUsages": { - "allowed": [ - "client_auth" - ] - }, - "algorithms": { - "signature": [ - "SHA256-RSA" - ], - "keyAlgorithm": [ - "RSA-2048" - ] - }, - "validity": { - "max": "365d" - } - }' - ``` - - ### Sample response - - ```bash Response - { - "certificateTemplate": { - "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a", - "projectId": "3c90c3cc-0d44-4b50-8888-8dd25736052a", - "name": "", - "description": "", - "subject": [ - { - "type": "common_name", - "allowed": [ - "*.infisical.com" - ] - } - ], - "sans": [ - { - "type": "dns_name", - "allowed": [ - "*.sample.com" - ] - } - ], - "keyUsages": { - "allowed": [ - "digital_signature" - ] - }, - "extendedKeyUsages": { - "allowed": [ - "client_auth" - ] - }, - "algorithms": { - "signature": [ - "SHA256-RSA" - ], - "keyAlgorithm": [ - "RSA-2048" - ] - }, - "validity": { - "max": "365d" - }, - "createdAt": "2023-11-07T05:31:56Z", - "updatedAt": "2023-11-07T05:31:56Z" - } - } - ``` - - - - To create a certificate under the certificate template, make an API request to the [Issue Certificate](/api-reference/endpoints/certificates/issue-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' \ - --header 'Content-Type: application/json' \ - --data-raw '{ - "profileId": "", - "commonName": "service.acme.com", - "ttl": "1y", - "signatureAlgorithm": "RSA-SHA256", - "keyAlgorithm": "RSA_2048" - }' - ``` - - ### Sample response - - ```bash Response - { - certificate: "...", - certificateChain: "...", - issuingCaCertificate: "...", - privateKey: "...", - serialNumber: "..." - } - ``` - - - Note that Infisical PKI supports issuing certificates without certificate templates as well. If this is desired, then you can set the **Certificate Template** field to **None** - and specify the **Issuing CA** and optional **Certificate Collection** fields; the rest of the fields for the issued certificate remain the same. - - That said, we recommend using certificate templates to enforce policies and attach expiration monitoring on issued certificates. - - - - 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. - - ### Sample request - - ```bash Request - curl --location --request POST 'https://app.infisical.com/api/v1/cert-manager/certificates/sign-certificate' \ - --header 'Content-Type: application/json' \ - --data-raw '{ - "certificateTemplateId": "", - "csr": "...", - "ttl": "1y", - }' - ``` - - ### Sample response - - ```bash Response - { - certificate: "...", - certificateChain: "...", - issuingCaCertificate: "...", - privateKey: "...", - serialNumber: "..." - } - ``` - - - - - - -## Guide to Revoking Certificates - -In the following steps, we explore how to revoke a X.509 certificate under a CA and obtain a Certificate Revocation List (CRL) for a CA. - - - - - - Assuming that you've issued a certificate under a CA, you can revoke it by - selecting the **Revoke Certificate** option for it and specifying the reason - for revocation. - - ![pki revoke certificate](/images/platform/pki/certificate/cert-revoke.png) - - ![pki revoke certificate modal](/images/platform/pki/certificate/cert-revoke-modal.png) - - - - In order to check the revocation status of a certificate, you can check it - against the CRL of a CA by heading to its Issuing CA and downloading the CRL. - - ![pki view crl](/images/platform/pki/ca/ca-crl.png) - - To verify a certificate against the - downloaded CRL with OpenSSL, you can use the following command: - -```bash -openssl verify -crl_check -CAfile chain.pem -CRLfile crl.pem cert.pem -``` - -Note that you can also obtain the CRL from the certificate itself by -referencing the CRL distribution point extension on the certificate. - -To check a certificate against the CRL distribution point specified within it with OpenSSL, you can use the following command: - -```bash -openssl verify -verbose -crl_check -crl_download -CAfile chain.pem cert.pem -``` - - - - - - - - Assuming that you've issued a certificate under a CA, you can revoke it by making an API request to the [Revoke Certificate](/api-reference/endpoints/certificates/revoke) API endpoint, - specifying the serial number of the certificate and the reason for revocation. - - ### Sample request - - ```bash Request - curl --location --request POST 'https://app.infisical.com/api/v1/cert-manager/certificates//revoke' \ - --header 'Authorization: Bearer ' \ - --header 'Content-Type: application/json' \ - --data-raw '{ - "revocationReason": "UNSPECIFIED" - }' - ``` - - ### Sample response - - ```bash Response - { - message: "Successfully revoked certificate", - serialNumber: "...", - revokedAt: "..." - } - ``` - - - In order to check the revocation status of a certificate, you can check it against the CRL of the issuing CA. - To obtain the CRLs of the CA, make an API request to the [List CRLs](/api-reference/endpoints/certificate-authorities/crl) API endpoint. - - ### Sample request - - ```bash Request - curl --location --request GET 'https://app.infisical.com/api/v1/cert-manager/ca/internal//crls' \ - --header 'Authorization: Bearer ' - ``` - - ### Sample response - - ```bash Response - [ - { - id: "...", - crl: "..." - }, - ... - ] - ``` - - To verify a certificate against the CRL with OpenSSL, you can use the following command: - - ```bash - openssl verify -crl_check -CAfile chain.pem -CRLfile crl.pem cert.pem - ``` - - - - - - -## FAQ - - - - To renew a certificate, you have to issue a new certificate from the same CA - with the same common name as the old certificate. The original certificate - will continue to be valid through its original TTL unless explicitly - revoked. - - diff --git a/docs/documentation/platform/pki/certificates/certificates.mdx b/docs/documentation/platform/pki/certificates/certificates.mdx index eab06fe435..1f2a5b7f2b 100644 --- a/docs/documentation/platform/pki/certificates/certificates.mdx +++ b/docs/documentation/platform/pki/certificates/certificates.mdx @@ -29,13 +29,13 @@ Refer to the documentation for each [enrollment method](/documentation/platform/ ## Guide to Renewing Certificates To [renew a certificate](/documentation/platform/pki/concepts/certificate-lifecycle#renewal), you can either request a new certificate from a certificate profile or have the platform -automatically request a new one for you. Whether you pursue a client-driven or server-driven approach is totally dependent on the enrollment method configured on your certificate +automatically request a new one for you to be delivered downstream to a target destination. Whether you pursue a client-driven or server-driven approach is totally dependent on the enrollment method configured on your certificate profile as well as your infrastructure use-case. ### Client-Driven Certificate Renewal Client-driven certificate renewal is when renewal is initiated client-side by the end-entity consuming the certificate. -This is the most common approach to certificate renewal and is suitable for most use-cases. +More specifically, the client (e.g. [Infisical Agent](/integrations/platforms/certificate-agent), [ACME client](https://letsencrypt.org/docs/client-options/), etc.) monitors the certificate and makes a request for Infisical to issue a new certificate back to it when the existing certificate is nearing expiration. This is the most common approach to certificate renewal and is suitable for most use-cases. ### Server-Driven Certificate Renewal diff --git a/docs/documentation/platform/pki/enrollment-methods/api.mdx b/docs/documentation/platform/pki/enrollment-methods/api.mdx index bfbac7f2e1..a6a9d04dac 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,31 +135,39 @@ 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": "..." } ``` - 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. + Note: If the certificate is available to be issued immediately, the `certificate` field in the response will contain the certificate data. If issuance is delayed (for example, due to pending approval or additional processing), the `certificate` field will be `null` and you can use the `certificateRequestId` to poll for status or retrieve the certificate when it is ready using the [Get Certificate Request](/api-reference/endpoints/certificates/certificate-request) API endpoint. + + Also be 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 +175,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..90bddeacb2 --- /dev/null +++ b/docs/integrations/platforms/certificate-agent.mdx @@ -0,0 +1,552 @@ +--- +title: "Infisical Agent" +sidebarTitle: "Infisical Agent" +description: "Learn how to use Infisical CLI Agent to manage certificates automatically." +--- + +## Concept + +The Infisical Agent is a client daemon that is packaged into the [Infisical CLI](/cli/overview). +It can be used to request a certificate from Infisical using the [API enrollment method](/documentation/platform/pki/enrollment-methods/api) configured on a [certificate profile](/documentation/platform/pki/certificates/profiles), persist it to a specified path on the filesystem, and automatically monitor and renew it before expiration. + +The Infisical Agent is notable: + +- Automating certificate management: The agent can request, persist, monitor, and renew certificates from Infisical automatically without manual intervention. It also supports post-event hooks to execute custom commands after certificate issuance, renewal, or failure events. +- Leveraging workload identity: The agent can authenticate with Infisical as a [machine identity](/documentation/platform/identities/machine-identities) using an infrastructure-native authentication method such as [AWS Auth](/docs/documentation/platform/identities/aws-auth), [Azure Auth](/docs/documentation/platform/identities/azure-auth), [GCP Auth](/docs/documentation/platform/identities/gcp-auth), [Kubernetes Auth](/docs/documentation/platform/identities/kubernetes-auth), etc. + +The typical workflow for using the agent involves installing the Infisical CLI on the target machine, creating a configuration file defining the certificate to request and how it should be managed, and then starting the agent with that configuration so it can request, persist, monitor, and renew the certificate before it expires. +This follows a [client-driven approach](/documentation/platform/pki/certificates/certificates#client-driven-certificate-renewal) to certificate renewal. + +## Workflow + +A typical workflow for using the Infisical Agent to request certificates from Infisical consists of the following steps: + +1. Create a [certificate profile](/documentation/platform/pki/certificates/profiles) in Infisical with the [API enrollment method](/documentation/platform/pki/enrollment-methods/api) configured on it. +2. Install the [Infisical CLI](/cli/overview) on the target machine. +3. Create an agent [configuration file](/integrations/platforms/certificate-agent#agent-configuration) containing details about the certificate to request and how it should be managed such as renewal thresholds, post-event hooks, etc. +4. Start the agent with that configuration so it can request, persist, monitor, and going forward automatically renew the certificate before it expires on the target machine. + +## Operating the Agent + +This section describes how to use the Infisical Agent to request certificates from Infisical. It covers how the agent authenticates with Infisical, +and how to configure it to start requesting certificates from Infisical. + +### Authentication + +The Infisical Agent can authenticate with Infisical as a [machine identity](/documentation/platform/identities/machine-identities) using one of its supported authentication methods. + +Upon successful authentication, the agent receives a short-lived access token that it uses to make subsequent authenticated requests to obtain and renew certificates from Infisical; +the agent automatically handles token renewal as documented [here](/integrations/platforms/infisical-agent#token-renewal). + + + + 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" + ``` + + + + + + +### Agent Configuration + +The Infisical Agent relies on a YAML configuration file to define its behavior, including how it should authenticate with Infisical, the certificate it should request, and how that certificate should be managed including auto-renewal. + +The code snippet below shows an example configuration file that instructs the agent to request and continuously renew a certificate from Infisical. + +Note that not all configuration options in this file are required but this example includes all of the available options. + +```yaml example-cert-agent-config.yaml +version: v1 + +# Infisical server configuration +infisical: + address: "https://app.infisical.com" # The URL of the Infisical instance (e.g. https://app.infisical.com, https://eu.infisical.com, https://your-self-hosted-instance.com) + retry-strategy: + max-retries: 3 + max-delay: "5s" + base-delay: "200ms" + +# Infisical authentication configuration +auth: + type: "universal-auth" # The authentication method to use (e.g. universal-auth, kubernetes-auth, azure-auth, gcp-id-token, gcp-iam, aws-iam) + config: + client-id: "your-client-id" + client-secret: "your-client-secret" + +# Certificate configuration +certificates: + - profile-name: "prof-web-server-12345" + project-slug: "my-project-slug" + attributes: + common-name: "api.example.com" + alt-names: ["api.example.com", "api-v2.example.com"] + ttl: "90d" + key-algorithm: "RSA_2048" + signature-algorithm: "RSA-SHA256" + key-usages: + - "digital_signature" + - "key_encipherment" + extended-key-usages: + - "server_auth" + + # Enable automatic certificate renewal + lifecycle: + renew-before-expiry: "30d" + status-check-interval: "6h" + + # Configure where to store the issued certificate and its associated private key and certificate chain + file-output: + private-key: + path: "/etc/ssl/private/web.key" + permission: "0600" # Read/write for owner only + certificate: + path: "/etc/ssl/certs/web.crt" + permission: "0644" # Read for all, write for owner + chain: + path: "/etc/ssl/certs/web-chain.crt" + permission: "0644" # Read for all, write for owner + omit-root: true # Exclude the root CA certificate in chain + + # Configure custom commands to execute after certificate issuance, renewal, or failure events + 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 +``` + +To be more specific, the configuration file instructs the agent to: + +- Authenticate with Infisical using the [Universal Auth](/integrations/platforms/certificate-agent#universal-auth) authentication method. +- Request a 90-day certificate against the [certificate profile](/documentation/platform/pki/certificates/profiles) named `prof-web-server-12345` with the common name `web.company.com` and the subject alternative names `web.company.com` and `www.company.com`. +- Automatically renew the certificate 30 days before expiration by checking the certificate status every 6 hours and retrying up to 3 times with a base delay of 200ms and a maximum delay of 5s if the certificate status check fails. +- Store the certificate and its associated private key and certificate chain (excluding the root CA certificate) in the filesystem at the specified paths with the specified permissions. +- Execute custom commands after certificate issuance, renewal, or failure events such as reloading an `nginx` service or sending an email notification. + +### Agent Execution + +After creating the configuration file, you can run the command below with the `--config` flag pointing to the path where the agent configuration file is located. + +```bash +infisical cert-manager agent --config /path/to/your/agent-config.yaml +``` + +This will start the agent 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, you may consider running the agent as a system service to ensure it starts automatically and runs continuously. + +### Agent Certificate Configuration Parameters + +The table below provides a complete list of parameters that can be configured in the **certificate configuration** section of the agent configuration file: + +| Parameter | Required | Description | +| ------------------------------------ | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `profile-name` | Yes | The name of the [certificate profile](/documentation/platform/pki/certificates/profiles) to request a certificate against (e.g., `web-server-12345`) | +| `project-slug` | Yes | The slug of the project to request a certificate against (e.g., `my-project-slug`) | +| `common-name` | Optional | The common name for the certificate (e.g. `www.example.com`) | +| `alt-names` | Optional | The list of subject alternative names for the certificate (e.g., `["www.example.com", "api.example.com"]`) | +| `ttl` | Optional (uses profile default if not specified) | The time-to-live duration for the certificate, specified as a duration string (e.g. `72h`, `90d`, `1y`, etc.) | +| `key-algorithm` | Optional | The algorithm for the certificate key pair. One of: `RSA_2048`, `RSA_3072`, `RSA_4096`, `EC_prime256v1`, `EC_secp384r1`, `EC_secp521r1`. | +| `signature-algorithm` | Optional | The algorithm used to sign the certificate. One of: `RSA-SHA256`, `RSA-SHA384`, `RSA-SHA512`, `ECDSA-SHA256`, `ECDSA-SHA384`, `ECDSA-SHA512`. | +| `key-usages` | Optional | The list of key usage values for the certificate. One or more of: `digital_signature`, `key_encipherment`, `non_repudiation`, `data_encipherment`, `key_agreement`, `key_cert_sign`, `crl_sign`, `encipher_only`, `decipher_only`. | +| `extended-key-usages` | Optional | The list of extended key usage values for the certificate. One or more of: `server_auth`, `client_auth`, `code_signing`, `email_protection`, `timestamping`, `ocsp_signing`. | +| `csr-path` | Conditional | The path to a certificate signing request (CSR) file (e.g., `./csr/webserver.csr`, `/etc/ssl/csr.pem`). This is required if using a pre-generated CSR. | +| `file-output.private-key.path` | Optional (required if the `csr-path` is not specified) | The path to store the private key (required if not using a CSR) | +| `file-output.private-key.permission` | Optional (defaults to `0600`) | The octal file permissions for the private key file (e.g. `0600`) | +| `file-output.certificate.path` | Yes | The path to store the issued certificate in the filesystem | +| `file-output.certificate.permission` | Optional (defaults to `0600`) | The octal file permissions for the certificate file (e.g. `0644`) | +| `file-output.chain.path` | Optional | The path to store the certificate chain in the filesystem. | +| `file-output.chain.permission` | Optional (defaults to `0600`) | The octal permissions for the chain file (e.g. `0644`) | +| `file-output.chain.omit-root` | Optional (defaults to `true`) | Whether to exclude the root CA certificate from the returned certificate chain | +| `lifecycle.renew-before-expiry` | Optional (auto-renewal is disabled if not set) | Duration before certificate expiration when renewal checks should begin, specified as a duration string (e.g. `72h`, `90d`, `1y`, etc.) | +| `lifecycle.status-check-interval` | Optional (defaults to `10s`) | How frequently the agent checks certificate status and renewal needs, specified as a duration string (e.g. `10s`, `30m`, `1d`, etc.) | +| `post-hooks.on-issuance.command` | Optional | The shell command to execute after a certificate is successfully issued for the first time (e.g., `systemctl reload nginx`, `/usr/local/bin/reload-service.sh`) | +| `post-hooks.on-issuance.timeout` | Optional (defaults to `30`) | Maximum execution time in seconds for the on-issuance post-hook command before it is terminated (e.g., `30`, `60`, `120`) | +| `post-hooks.on-renewal.command` | Optional | The shell command to execute after a certificate is successfully renewed (e.g., `systemctl reload nginx`, `docker restart web-server`) | +| `post-hooks.on-renewal.timeout` | Optional (defaults to `30`) | Maximum execution time in seconds for the on-renewal post-hook command before it is terminated (e.g., `30`, `60`, `120`) | +| `post-hooks.on-failure.command` | Optional | The shell command to execute when certificate issuance or renewal fails (e.g., `logger 'Certificate renewal failed'`, `/usr/local/bin/alert.sh`) | +| `post-hooks.on-failure.timeout` | Optional (defaults to `30`) | Maximum execution time in seconds for the on-failure post-hook command before it is terminated (e.g., `10`, `30`, `60`) | + +### Post-Event Hooks + +The Infisical Agent supports running custom commands in response to certificate lifecycle events such as issuance, renewal, and failure through the `post-hooks` configuration +in the agent configuration file. + + + + 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 + ``` + + + + +### Retrying mechanism + +The Infisical Agent will automatically attempt to retry any failed API requests including 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 +``` + +## Example Agent Configuration Files + +Since there are several ways you might want to use the Infisical Agent to request certificates from Infisical, +we provide a few example configuration files for common use cases below to help you get started. + +### One-Time Certificate Issuance + +The code snippet below shows a configuration file that instructs the agent to request a certificate from Infisical +once without performing any subsequent auto-renewal. + +```yaml +version: v1 + +# Infisical server configuration +infisical: + address: "https://app.infisical.com" # The URL of the Infisical instance (e.g. https://app.infisical.com, https://eu.infisical.com, https://your-self-hosted-instance.com) + retry-strategy: + max-retries: 3 + max-delay: "5s" + base-delay: "200ms" + +# Infisical authentication configuration +auth: + type: "universal-auth" # The authentication method to use (e.g. universal-auth, kubernetes-auth, azure-auth, gcp-id-token, gcp-iam, aws-iam) + config: + client-id: "your-client-id" + client-secret: "your-client-secret" + +# Certificate configuration +certificates: + - profile-name: "prof-web-server-12345" + project-slug: "my-project-slug" + attributes: + common-name: "api.example.com" + alt-names: + - "api.example.com" + - "api-v2.example.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: "/etc/ssl/private/api.example.com.key" + permission: "0600" + certificate: + path: "/etc/ssl/certs/api.example.com.crt" + permission: "0644" + chain: + path: "/etc/ssl/certs/api.example.com.chain.crt" + permission: "0644" + omit-root: true +``` + +### One-Time Certificate Issuance using a Pre-Generated CSR + +The code snippet below shows a configuration file that instructs the agent to request a certificate from Infisical +once using a pre-generated CSR. + +Note that when `csr-path` is specified: + +- The `private-key` is omitted from the configuration file because we assume that it is pre-generated and managed externally, with only the CSR being submitted to Infisical for signing. +- The agent will not be able to perform any auto-renewal operations, as it is assumed to not have access to the private key required to generate a new CSR. + +```yaml +version: v1 + +# Infisical server configuration +infisical: + address: "https://app.infisical.com" # The URL of the Infisical instance (e.g. https://app.infisical.com, https://eu.infisical.com, https://your-self-hosted-instance.com) + retry-strategy: + max-retries: 3 + max-delay: "5s" + base-delay: "200ms" + +# Infisical authentication configuration +auth: + type: "universal-auth" # The authentication method to use (e.g. universal-auth, kubernetes-auth, azure-auth, gcp-id-token, gcp-iam, aws-iam) + config: + client-id: "your-client-id" + client-secret: "your-client-secret" + +# Certificate configuration +certificates: + - profile-name: "prof-web-server-12345" + project-slug: "my-project-slug" + csr-path: "/etc/ssl/requests/api.csr" + file-output: + certificate: + path: "/etc/ssl/certs/api.example.com.crt" + permission: "0644" + chain: + path: "/etc/ssl/certs/api.example.com.chain.crt" + permission: "0644" + omit-root: true +``` + +### Certificate Issuance with Automatic Renewal + +The code snippet below shows a configuration file that instructs the agent to request a certificate from Infisical and continuously renew it 14 days before expiration, checking the certificate status every 6 hours. + +```yaml +version: v1 + +# Infisical server configuration +infisical: + address: "https://app.infisical.com" # The URL of the Infisical instance (e.g. https://app.infisical.com, https://eu.infisical.com, https://your-self-hosted-instance.com) + retry-strategy: + max-retries: 3 + max-delay: "5s" + base-delay: "200ms" + +# Infisical authentication configuration +auth: + type: "universal-auth" # The authentication method to use (e.g. universal-auth, kubernetes-auth, azure-auth, gcp-id-token, gcp-iam, aws-iam) + config: + client-id: "your-client-id" + client-secret: "your-client-secret" + +# Certificate configuration +certificates: + - profile-name: "prof-web-server-12345" + project-slug: "my-project-slug" + attributes: + common-name: "api.example.com" + alt-names: + - "api.example.com" + - "api-v2.example.com" + key-algorithm: "RSA_2048" + signature-algorithm: "RSA-SHA256" + key-usages: + - "digital_signature" + - "key_encipherment" + extended-key-usages: + - "server_auth" + ttl: "30d" + 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: "/etc/ssl/private/api.example.com.key" + permission: "0600" + certificate: + path: "/etc/ssl/certs/api.example.com.crt" + permission: "0644" + chain: + path: "/etc/ssl/certs/api.example.com.chain.crt" + permission: "0644" + post-hooks: + on-issuance: + command: "systemctl reload nginx" + timeout: 30 + on-renewal: + command: "systemctl reload nginx && logger 'Certificate renewed'" + timeout: 30 +```