Skip to content

CertIntel plugin for Posh-ACME

Requires Posh-ACME 4.7+ (4.x) and Windows PowerShell 5.1 or PowerShell 7. The plugin is the single CertIntel.ps1 file, Posh-ACME's native plugin format.

No separate JSON configuration is needed. Pass delegation details as plugin arguments and API keys as SecureString values. Posh-ACME saves the arguments for renewal and protects secure values using the account's encryption settings. It manages its own configuration files automatically.

Install

From a trusted checkout of the CertIntel plugins repository, download a verified package, then execute the verified installer for the current user:

.\scripts\Get-CertIntelPackage.ps1 -Client posh-acme -Directory .\verified\posh-acme `
  -StatePath "$env:LOCALAPPDATA\CertIntel\Releases\posh-acme.json"
if ($?) { & .\verified\posh-acme\Install-PoshAcme.ps1 }

For all users, run the verified installer from an elevated PowerShell session:

& .\verified\posh-acme\Install-PoshAcme.ps1 -Scope AllUsers

The bootstrap pins the agent's Authenticode signing certificate before running the verifier. The verifier authenticates the Ed25519 release manifest, rejects expired or older releases, and checks every file's URL, size and SHA-256. Keep the state file between upgrades. See release verification. Never execute an installer obtained from an unverified download.

The installer checks user and machine module folders for both Windows PowerShell and PowerShell 7 and selects the newest supported Posh-ACME version. If it is missing, it displays the Posh-ACME installation page and stops. Install Posh-ACME, then run the installer again.

By default, the plugin is installed for the current user in %LOCALAPPDATA%\CertIntel\Posh-ACME\Plugins, even if the module is installed machine-wide. An existing POSHACME_PLUGINS folder is reused. The installer creates the directory, verifies the signed release and the plugin's Authenticode signature, sets POSHACME_PLUGINS in the current session and for future sessions, imports Posh-ACME, and displays Get-PAPlugin CertIntel -Params automatically. The plugin is ready to use in the same session.

All-users installation defaults to %ProgramData%\CertIntel\Posh-ACME\Plugins and persists the machine environment setting. Existing user settings can override that path in future sessions; the installer warns if one exists. Re-running the installer updates the plugin. It does not install Posh-ACME or configure API keys, certificate orders or scheduled tasks. Other already-running PowerShell sessions and scheduled renewal processes need the same plugin path and access permissions. The installer prints an import command for future sessions using the detected module's full path. Use that command if the module is installed for another PowerShell edition and is not found by Import-Module Posh-ACME in your chosen shell.

For manual installation or other platforms, use the cross-platform verifier in release verification, then put the verified CertIntel.ps1 in a permanent folder. For example:

$env:POSHACME_PLUGINS = 'C:\CertIntel\plugins'
Import-Module Posh-ACME -Force
Get-PAPlugin CertIntel -Params

Set POSHACME_PLUGINS before import and in your scheduled renewal script. Keeping the plugin outside the module's installation folder prevents module updates from removing it. PowerShell 7 users on other platforms can substitute their own absolute paths.

Create a delegation in CertIntel and its permanent CNAME at your DNS provider:

_acme-challenge.example.com -> YOUR-LABEL.dns01.certin.tel

Save the delegation UUID, full CNAME target and update secret. A CertIntel DNS API key explicitly granted access to the delegation also works. example.com and *.example.com share one mapping. Other names require separate exact mappings.

Staging issuance without JSON

Set-PAServer LE_STAGE
$pluginArgs = @{
    CertIntelDomain       = 'example.com'
    CertIntelDelegationId = '11111111-1111-1111-1111-111111111111'
    CertIntelCnameTarget  = 'YOUR-LABEL.dns01.certin.tel'
    CertIntelApiKey       = Read-Host 'CertIntel API key' -AsSecureString
}
New-PACertificate 'example.com','*.example.com' -Plugin CertIntel `
    -PluginArgs $pluginArgs -DnsSleep 60 -AcceptTOS -Contact '[email protected]'

The API endpoint defaults to https://api.certin.tel/api/v1. To override it, add CertIntelApiBase = 'https://your-server.example/api/v1' to the hashtable. Certificate hostnames must not contain underscores; the _acme-challenge record prefix does contain a required underscore.

This performs DNS validation and writes Posh-ACME's certificate files without installing them into a server. Confirm issuance and TXT cleanup. Increase -DnsSleep if needed for DNS propagation.

Multiple delegations

Use arrays in matching domain order:

$pluginArgs = @{
    CertIntelDomain = @('example.com', 'www.example.com')
    CertIntelDelegationId = @(
        '11111111-1111-1111-1111-111111111111'
        '22222222-2222-2222-2222-222222222222'
    )
    CertIntelCnameTarget = @('FIRST-LABEL.dns01.certin.tel', 'SECOND-LABEL.dns01.certin.tel')
    CertIntelApiKey = @(
        (Read-Host 'API key for example.com' -AsSecureString)
        (Read-Host 'API key for www.example.com' -AsSecureString)
    )
}
New-PACertificate 'example.com','*.example.com','www.example.com' -Plugin CertIntel `
    -PluginArgs $pluginArgs -DnsSleep 60 -AcceptTOS -Contact '[email protected]'

CertIntelApiKey may also be one shared secure key with grants for every delegation. CertIntelApiBase accepts one shared endpoint or one per domain. Keep secure keys in the top-level CertIntelApiKey argument; do not put them in nested hashtables or convert them to JSON.

Credential protection and vaults

On Windows, default DPAPI protection depends on the user and machine. Run renewals under the setup account. Linux/macOS users should enable Posh-ACME's alternative plugin encryption.

Posh-ACME 4.11+ can store its encryption key in a SecretManagement vault; API credentials remain encrypted in its order files. After installing SecretManagement and registering a writable vault:

$env:POSHACME_VAULT_NAME = 'YourRegisteredVault'
Set-PAAccount -UseAltPluginEncryption

For a new account, use New-PAAccount -AcceptTOS -Contact '[email protected]' -UseAltPluginEncryption. Verify account sskey is VAULT and VaultGuid is populated. If alternative encryption was already enabled, follow the official migration steps. Renewals need noninteractive vault access. See the SecretManagement guide.

You can obtain the initial API key with Get-Secret if it returns a SecureString. Posh-ACME saves that value; it is not a live reference to the individual API-key secret. After rotating a key, update the selected order with the full argument set using Set-PAOrder -PluginArgs $pluginArgs.

See also the plugin development guide.

Renewal and production

With the staging order selected, test renewal using Submit-Renewal -Force. Saved plugin arguments are reused; no key prompt or JSON file editing is needed. For production, select Set-PAServer LE_PROD and create a production order using the same delegation arguments. A staging certificate is not publicly trusted.

A scheduled script should set POSHACME_PLUGINS, import Posh-ACME, select the intended server, then run Submit-Renewal -AllAccounts. Set any vault or custom POSHACME_HOME environment variables used during setup as well. Test the script under the actual renewal account.

Locks default to .certintel-locks in Posh-ACME's configuration root. Use one issuing client/host per delegation, with a consistent lock directory. Do not run the dedicated CertIntel agent concurrently against the same delegation. The API permits at most two TXT values and cannot protect against writers on other hosts.

Production and scheduled command examples

After the staging test, create the production order in the same PowerShell session (using the $pluginArgs from setup):

Set-PAServer LE_PROD
New-PACertificate 'example.com','*.example.com' -Plugin CertIntel `
    -PluginArgs $pluginArgs -DnsSleep 60 -AcceptTOS -Contact '[email protected]'

For a Windows scheduled task, save the following as a script and run it with PowerShell under the same Windows account used for setup. Replace the plugin path with the installer's path. Choose a regular schedule, such as twice daily:

$ErrorActionPreference = 'Stop'
$env:POSHACME_PLUGINS = 'C:\CertIntel\plugins'
Import-Module Posh-ACME -MinimumVersion 4.7.0 -MaximumVersion 4.999.999 -Force
Set-PAServer LE_PROD
Submit-Renewal -AllAccounts

This renews certificate files when due. Configure a separate deployment step if your application needs certificate import, an IIS binding update or a reload.

Optional CertIntel reporting

The DNS plugin does not send check-ins or renewal reports. Use the separate Posh-ACME reporting wrappers if you want those reports. They accept -PluginDirectory for custom plugin discovery and -DirectoryUrl LE_PROD (or LE_STAGE) to select the CA. The issuance wrapper takes -Plugin CertIntel -PluginArgs $pluginArgs -DnsSleep 60. Schedule the renewal wrapper in place of the direct command above; it processes the current account's orders. Set the same account, configuration root and vault environment used at setup. Its write-scoped reporting key is separate from the DNS plugin's delegation credential.

Troubleshooting

Symptom Check
CertIntel is missing from Get-PAPlugin Set POSHACME_PLUGINS before importing Posh-ACME with -Force; verify the renewal account can read CertIntel.ps1.
No delegation matches Use the exact certificate name without *. or _acme-challenge.; subdomains need their own mapping.
API 401/403 Check the update secret or DNS API key grants, delegation status and API endpoint.
Saved secret cannot be decrypted Run as the setup account on the same Windows machine, or restore access to the configured alternative encryption key/vault.
DNS validation fails Verify the permanent CNAME and public TXT answers; increase -DnsSleep if necessary.
Two TXT values already exist Confirm no other client is issuing; remove stale values only after confirming no issuance is active.

See shared delegation ownership guidance.