The ODDC Server uses a secure HTTPS connection, which requires a trusted server certificate.*
You can use an existing certificate. You must specify the certificate’s thumbprint in the ar.oddc.server.config.json file, under the “CertificateThumbprint” section:
"CertificateThumbprint": "yourTHUMBPRINThere"
Ensure that the technical user has read access to the certificate.
*If you do not have a certificate for setup, create a self-signed certificate for internal use; the user must have read access to it. See the script below (Windows Server 2025).
Create self-signed certificate (Powershell script)
#Requires -RunAsAdministrator
$ErrorActionPreference = "Stop"
# Get the server names
$serverName = $env:COMPUTERNAME
$serverNameLocal = "$serverName.local"
# Local Windows account that needs access to the private key
$userName = "$serverNameoddc_techuser"
# Verify that the user account exists
try {
$account = New-Object System.Security.Principal.NTAccount($userName)
$null = $account.Translate(
[System.Security.Principal.SecurityIdentifier]
)
}
catch {
throw "The Windows account '$userName' does not exist or cannot be resolved."
}
# 1. Create the self-signed certificate in LocalMachineMy
$cert = New-SelfSignedCertificate `
-DnsName $serverName, $serverNameLocal, "localhost" `
-CertStoreLocation "Cert:LocalMachineMy" `
-FriendlyName "ODDC Server 5.1 self-signed certificate" `
-KeyAlgorithm RSA `
-KeyLength 2048 `
-KeyUsage DigitalSignature, KeyEncipherment `
-TextExtension @(
"2.5.29.37={text}1.3.6.1.5.5.7.3.1"
) `
-NotAfter (Get-Date).AddYears(1)
Write-Host "Certificate created in LocalMachineMy."
# 2. Add the certificate to LocalMachineRoot
$tempCertPath = Join-Path $env:TEMP "$serverName-$($cert.Thumbprint).cer"
try {
Export-Certificate `
-Cert $cert `
-FilePath $tempCertPath `
-Force | Out-Null
Import-Certificate `
-FilePath $tempCertPath `
-CertStoreLocation "Cert:LocalMachineRoot" | Out-Null
Write-Host "Certificate added to LocalMachineRoot."
}
finally {
if (Test-Path $tempCertPath) {
Remove-Item -Path $tempCertPath -Force
}
}
# 3. Locate the certificate's private key
$certPath = "Cert:LocalMachineMy$($cert.Thumbprint)"
$cert = Get-Item -Path $certPath
if (-not $cert.HasPrivateKey) {
throw "The certificate does not have a private key."
}
$rsa = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey(
$cert
)
if ($null -eq $rsa) {
throw "The RSA private key could not be opened."
}
try {
if ($rsa -is [System.Security.Cryptography.RSACng]) {
# CNG private keys are stored in:
# C:ProgramDataMicrosoftCryptoKeys
$keyFilePath = Join-Path `
"$env:ProgramDataMicrosoftCryptoKeys" `
$rsa.Key.UniqueName
$providerType = "CNG"
}
elseif ($rsa -is [System.Security.Cryptography.RSACryptoServiceProvider]) {
# Legacy CSP private keys are stored in:
# C:ProgramDataMicrosoftCryptoRSAMachineKeys
$keyFilePath = Join-Path `
"$env:ProgramDataMicrosoftCryptoRSAMachineKeys" `
$rsa.CspKeyContainerInfo.UniqueKeyContainerName
$providerType = "CSP"
}
else {
throw "Unsupported RSA provider: $($rsa.GetType().FullName)"
}
if (-not (Test-Path -LiteralPath $keyFilePath)) {
throw "The private key file was not found: $keyFilePath"
}
# 4. Grant Read permission to oddc_techuser
$acl = Get-Acl -LiteralPath $keyFilePath
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
$userName,
[System.Security.AccessControl.FileSystemRights]::Read,
[System.Security.AccessControl.AccessControlType]::Allow
)
$acl.AddAccessRule($accessRule) | Out-Null
Set-Acl `
-LiteralPath $keyFilePath `
-AclObject $acl
# 5. Verify the resulting permission
$permission = (Get-Acl -LiteralPath $keyFilePath).Access |
Where-Object {
$_.IdentityReference.Value -eq $userName -and
$_.AccessControlType -eq "Allow" -and
($_.FileSystemRights -band
[System.Security.AccessControl.FileSystemRights]::Read)
}
if (-not $permission) {
throw "The private key permission could not be verified."
}
Write-Host ""
Write-Host "Private key permission successfully added."
Write-Host "Account: $userName"
Write-Host "Permission: Read"
Write-Host "Provider: $providerType"
Write-Host "Private key: $keyFilePath"
}
finally {
if ($null -ne $rsa) {
$rsa.Dispose()
}
}
Write-Host ""
Write-Host "Certificate configuration completed successfully."
Write-Host "Thumbprint: $($cert.Thumbprint)"
Write-Host "DNS names: $serverName, $serverNameLocal, localhost"
