Configuration

alpinCertificateClient reads a single JSON configuration file — typically named config.json — that tells it where the alpinCertificateTool platform lives and how to authenticate against it:

{
  "baseURL": "https://d3signapp.alpin.it/alpinCertificateToolREST/api/",
  "apiKey": "YOUR_API_KEY"
}

Every invocation of the client points at this file via -c / --config. Keep it out of version control, since it carries your API key.

Installing the client

alpinCertificateClient ships as a single, self-contained jar file, alpinCertificateClient-1.0.0-complete.jar. Copy it to any directory on the target machine — Windows or Linux — there's nothing else to install, beyond having a Java 21 (or later) runtime available on that machine.

java -jar alpinCertificateClient-1.0.0-complete.jar -c C:\cert\config.json <command> ...

Sample scripts

We provide ready-made Bash and PowerShell sample scripts that show typical usage end to end, from requesting a certificate to installing it on your target system. The rest of this page walks through one of them, windows1.ps1, in detail — the same concepts apply to the Bash samples.

Howto for the powershell update script (windows1.ps1)

# Alpin Certificate Client Demo for Windows
#
# Command args:
# Usage: alpinCertificateClient order-auto [-hV] [--cert-file=CERT_PATH]
#        [--certificate-instance=CERTIFICATE_INSTANCE]
#        [--certificate-inventory=CERTIFICATE_INVENTORY] [--challenge-type=TYPE]
#        [--dnsprovider=DNSPROVIDER] [--key-file=KEY_FILE] [-p=PASSWORD]
#        [--pem-file=PEM_FILE] [--pfx-file=PFX_FILE] [--ttl=TTL]
#        [--dns-option=KEY=VALUE]... DOMAIN CA_ID SECRET [RENEW_DAYS]
# Order a certificate for a domain, automatically fulfilling the dns-01 challenge
# via a DNS provider
#       DOMAIN                Domain name (e.g. example.com or *.example.com for
#                               wildcard)
#       CA_ID                 Certificate authority identifier (lowercase
#                               alphanumeric, underscores, and hyphens)
#       SECRET                32-character secret used to decrypt the user and
#                               domain key pairs
#       [RENEW_DAYS]          If set, only proceed when no certificate exists yet
#                               for this domain, or the existing one is already
#                               expired or expires within this many days;
#                               otherwise do nothing
#       --cert-file=CERT_PATH File to which the domain's certificate should be
#                               exported
#       --certificate-instance=CERTIFICATE_INSTANCE
#                             The certificate's key inside the certificate
#                               inventory
#       --certificate-inventory=CERTIFICATE_INVENTORY
#                             Path to a .json file that consists of key-value
#                               pairs, where the key is the certificate instance
#                               and they value is that certificate's expiration
#                               date
#       --challenge-type=TYPE ACME challenge type to fulfill: DNS01 (default),
#                               DNSPERSIST01, or DNSHOSTED01
#       --dns-option=KEY=VALUE
#                             Provider-specific option (zoneId=.../apiToken=...
#                               for cloudflare; hostedZoneId=.../accessKeyId=...
#                               /secretAccessKey=... for route53); may be
#                               repeated; ignored for --challenge-type DNSHOSTED01
#       --dnsprovider=DNSPROVIDER
#                             DNS provider to use for automated challenge
#                               fulfillment (must be listed in the dnsProviders
#                               config); required unless --challenge-type is
#                               DNSHOSTED01, which ignores it
#   -h, --help                Show this help message and exit.
#       --key-file=KEY_FILE   File to which the domain's key pair should be
#                               exported
#   -p, --password=PASSWORD   The password that should be used to protect the
#                               certificate. Only used if the --pfx-file or
#                               --pem-file options are specificed
#       --pem-file=PEM_FILE   File to which the domain's certificate should be
#                               exported (in pem format)
#       --pfx-file=PFX_FILE   File to which the domain's certificate should be
#                               exported (in pfx format)
#       --ttl=TTL             TTL in seconds for the DNS record; if omitted, the
#                               DNS provider applies its own default
#   -V, --version             Print version information and exit.

# Check and adapt the powershell execution policy if needed, for example:
# RemoteSigned allows locally created scripts to run, while scripts downloaded from the internet generally need to be signed (or explicitly unblocked).
#   Get-ExecutionPolicy -List
#   Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned

# Example to setup domain
#   java -jar alpinCertificateClient-1.0.0-complete.jar -c C:\cert\config.json setup sub.alpin.zone letsencrypt_stage ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef

# Set NO_COLOR if you want to skip ansi colors (as in elevated powershells)
#$env:NO_COLOR = 1
$env:NO_COLOR = $null

# Example to auto order certificate
java -jar alpinCertificateClient-1.0.0-complete.jar `
  -c C:\cert\config.json `
  order-auto sub.alpin.zone letsencrypt_stage ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef 5 `
  --challenge-type=DNSHOSTED01 `
  --pfx-file=C:\cert\domain.pfx `
  --pem-file=C:\cert\domain.pem `
  --password=password `
  --certificate-inventory=C:\cert\inventory.json `
  --certificate-instance=windows-server
# Store the client's exit code
$exitCode = $LASTEXITCODE

# Example for powershell postprocessing
# Note that you need to run this in an elevated powershell, if scheduling through task scheduler:
#   Create a new task (not a basic task)
#   General - Run whether user is loggoed on or not - Run with highest privileges
#   Actions - Program/script powershell.exe
#           - Add arguments  -NoProfile -ExecutionPolicy Bypass -File "C:\path\to\dir\renewalscript.ps1""
#           - Start in       C:\path\to\dir

# Example to load certificates in windows certificate store, restart services, kill processes
if ($exitCode -eq 0) {
  # CertStoreLocation: this machine "Cert:\LocalMachine\My" or current user "Cert:\CurrentUser\My"
  #Import-PfxCertificate -FilePath "C:\cert\domain.pfx" -CertStoreLocation "Cert:\LocalMachine\My" -Password (ConvertTo-SecureString "password" -AsPlainText -Force)

  # Restart Windows service if needed
  #Restart-Service -Name "AdobeARMservice" -Force

  # Terminate a specific process if needed
  #Stop-Process -Name "crash_reporter" -Force
}

exit $exitCode

The comment block at the top is the client's own --help output for the order-auto command — it's the authoritative reference for every option, and we'll return to it in the full parameter reference below. If the script itself refuses to run, see Allowing the script to run below.

Allowing the script to run

If PowerShell refuses to run windows1.ps1 at all — typically with an error about the file "not being digitally signed" — it's almost always because the script was downloaded from the internet (a browser or file share tags downloaded files this way) rather than created locally. Windows' default execution policy is intentionally stricter about downloaded scripts than about ones you wrote yourself. The script's own header comments cover the fix:

# Check and adapt the powershell execution policy if needed, for example:
# RemoteSigned allows locally created scripts to run, while scripts downloaded from the internet generally need to be signed (or explicitly unblocked).
#   Get-ExecutionPolicy -List
#   Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned

First-time setup for a domain

java -jar alpinCertificateClient-1.0.0-complete.jar -c C:\cert\config.json setup sub.alpin.zone letsencrypt_stage ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef

Run setup once per domain, the first time you want a certificate for it. It takes care of the one-time bootstrapping a domain needs before it can be issued a certificate: registering (or reusing) your account with the given Certificate Authority — here letsencrypt_stage, Let's Encrypt's sandbox environment — and generating the domain's key pair, both encrypted under your SECRET. Once this has run, the domain is ready for order-auto to issue and renew certificates against.

Checking, ordering, and renewing the certificate

java -jar alpinCertificateClient-1.0.0-complete.jar `
  -c C:\cert\config.json `
  order-auto sub.alpin.zone letsencrypt_stage ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef 5 `
  --challenge-type=DNSHOSTED01 `
  --pfx-file=C:\cert\domain.pfx `
  --pem-file=C:\cert\domain.pem `
  --password=password `
  --certificate-inventory=C:\cert\inventory.json `
  --certificate-instance=windows-server

This is the command you actually schedule to run every day. A few things worth calling out:

Scheduling the script to run daily

The whole point of order-auto is that it's safe to run every day and only does something on the days a renewal is actually due, so schedule it once and forget about it. On Windows, the built-in Task Scheduler is the usual way to do that. The script's own comments spell out the settings that matter:

# Note that you need to run this in an elevated powershell, if scheduling through task scheduler:
#   Create a new task (not a basic task)
#   General - Run whether user is loggoed on or not - Run with highest privileges
#   Actions - Program/script powershell.exe
#           - Add arguments  -NoProfile -ExecutionPolicy Bypass -File "C:\path\to\dir\renewalscript.ps1""
#           - Start in       C:\path\to\dir

One side effect of running elevated, non-interactively via Task Scheduler: alpinCertificateClient normally prints colored ANSI output, and that elevated PowerShell host may not render it correctly, showing raw escape codes instead of colored text. If you see that, disable coloring with the NO_COLOR environment variable the script already sets up for this purpose:

# Set NO_COLOR if you want to skip ansi colors (as in elevated powershells)
#$env:NO_COLOR = 1
$env:NO_COLOR = $null

Uncomment $env:NO_COLOR = 1 (and remove or comment out the $env:NO_COLOR = $null line below it) to make the client skip ANSI coloring entirely — useful whenever output is going somewhere that doesn't render color well, such as a Task Scheduler history log.

DNS-HOSTED-01

Using --challenge-type=DNSHOSTED01 is the most practical approach if your current DNS provider isn't one that offers an API to programmatically create, update, and delete DNS records.

Potentially in Q3/2026 or Q4/2026, there will be a DNS-PERSIST-01 challenge available. With that challenge type, you'll be able to set up a DNS TXT record once, and that same record will be sufficient for any subsequent certificate renewal. Since DNS-PERSIST-01 isn't officially available yet, we've implemented a similar approach as part of the alpinCertificateTool platform, which we call DNS-HOSTED-01.

With the DNS-HOSTED-01 challenge:

DNS-HOSTED-01 CNAME delegation Your DNS zone created once, by you Name: _acme-challenge.<domain> Type: CNAME TTL: 60 seconds (keep it short) points to certificatemanager.alpin.it operated by alpinCertificateTool Name: _acme-challenge.<domain, dashed> .certificatemanager.alpin.it Type: TXT (managed automatically) dynamically updated with the challenge value required by the Certificate Authority
The CNAME you create once in your own DNS zone points at a matching name under certificatemanager.alpin.it, which alpinCertificateTool keeps updated with the TXT value the Certificate Authority actually needs for each issuance or renewal.

This use case is totally simple. If, for example, you plan to create a certificate for the domain name

subdomain.yourdomain.tld

all you need to do is create a CNAME entry in your DNS:

_acme-challenge.subdomain.yourdomain.tld CNAME _acme-challenge.subdomain-yourdomain-tld.certificatemanager.alpin.it 60

Explained in detail:

Two real-world examples:

_acme-challenge.sub.alpin.zone CNAME _acme-challenge.sub-alpin-zone.certificatemanager.alpin.it 60
_acme-challenge.test.alpin.zone CNAME _acme-challenge.test-alpin-zone.certificatemanager.alpin.it 60

DNS-01 with an API-driven DNS provider

The example above uses DNS-HOSTED-01, which needs no DNS provider credentials at all. If your domain's DNS is already hosted with Cloudflare or AWS Route 53, you can instead use the standard DNS-01 challenge and let alpinCertificateClient manage the TXT record for you directly against your own DNS provider.

Example: Cloudflare

java -jar alpinCertificateClient-1.0.0-complete.jar `
  -c C:\cert\config.json `
  order-auto d3.alpin.it letsencrypt_stage ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef 5 `
  --challenge-type=DNS01 `
  --dnsprovider=cloudflare `
  --dns-option=zoneId="YOUR_CLOUDFLARE_ZONE_ID" `
  --dns-option=apiToken="YOUR_CLOUDFLARE_API_TOKEN" `
  --pfx-file=C:\cert\domain2.pfx `
  --pem-file=C:\cert\domain2.pem `
  --password=password `
  --certificate-inventory=C:\cert\inventory.json `
  --certificate-instance=windows-server2

Aside from the domain and file names, the only differences from the DNS-HOSTED-01 example are --challenge-type=DNS01, --dnsprovider=cloudflare, and the two --dns-option values — your Cloudflare zone ID and an API token scoped to manage DNS records in that zone.

Example: AWS Route 53

java -jar alpinCertificateClient-1.0.0-complete.jar `
  -c C:\cert\config.json `
  order-auto test.alpin.zone letsencrypt_stage ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef 1000 `
  --challenge-type=DNS01 `
  --dnsprovider=route53 `
  --dns-option=hostedZoneId="YOUR_ROUTE53_HOSTED_ZONE_ID" `
  --dns-option=accessKeyId="YOUR_AWS_ACCESS_KEY_ID" `
  --dns-option=secretAccessKey="YOUR_AWS_SECRET_ACCESS_KEY" `
  --ttl=60 `
  --pfx-file=C:\cert\domain3.pfx `
  --pem-file=C:\cert\domain3.pem `
  --password=password `
  --certificate-inventory=C:\cert\inventory.json `
  --certificate-instance=windows-server3

Here --dnsprovider=route53 takes three --dns-option values instead of two — a hosted zone ID and an AWS access key pair with permission to modify records in that zone — plus --ttl=60, which shortens the TXT record's TTL so the CA doesn't have to wait as long for it to propagate before validating the challenge. Note also RENEW_DAYS is 1000 here rather than 5: since no real certificate has 1000 days of validity left, this effectively forces a renewal on every run — handy while testing, but not what you'd want in a real nightly schedule.

Full parameter reference

Positional arguments, in order:

Argument Description
DOMAIN Domain name, e.g. example.com, or *.example.com for a wildcard certificate
CA_ID Certificate Authority identifier (lowercase alphanumeric, underscores, and hyphens)
SECRET 32-character secret used to decrypt your user and domain key pairs
RENEW_DAYS (optional, order-auto only) Only proceed if no certificate exists yet, or the existing one is expired or expires within this many days; otherwise do nothing

Options:

Option Description
--cert-file=CERT_PATH File to export the domain's certificate to
--certificate-instance=CERTIFICATE_INSTANCE The certificate's key inside the certificate inventory file
--certificate-inventory=CERTIFICATE_INVENTORY Path to a .json file mapping certificate instance names to that certificate's expiration date
--challenge-type=TYPE ACME challenge type to fulfill: DNS01 (default), DNSPERSIST01, or DNSHOSTED01
--dns-option=KEY=VALUE Provider-specific option — zoneId=... / apiToken=... for Cloudflare, hostedZoneId=... / accessKeyId=... / secretAccessKey=... for Route 53; may be repeated; ignored when --challenge-type=DNSHOSTED01
--dnsprovider=DNSPROVIDER DNS provider to use for automated challenge fulfillment; required unless --challenge-type=DNSHOSTED01
-h, --help Show the help message and exit
--key-file=KEY_FILE File to export the domain's key pair to
-p, --password=PASSWORD Password protecting the exported certificate; only used together with --pfx-file or --pem-file
--pem-file=PEM_FILE File to export the domain's certificate to, in PEM format
--pfx-file=PFX_FILE File to export the domain's certificate to, in PFX format
--ttl=TTL TTL in seconds for the DNS record; if omitted, the DNS provider's own default applies
-V, --version Print version information and exit