OAuth with an X.509 certificate
Authenticate to Okta using a Windows certificate, so the private key can be non-exportable or held in a TPM or HSM.
Background
Okta authenticates a service app by verifying a signed JWT against a public key it holds as a JWK. There are no certificates anywhere in that flow.
The management agent bridges the two. You give it a certificate thumbprint, and it finds the certificate in a Windows store, derives the public JWK from the certificate's public key, and signs each OAuth client assertion using the certificate's private key through the Windows cryptographic provider. The derived JWK is what you register in Okta.
The benefit of this approach is that Windows holds the private key, so it can be marked as non-exportable, or held in a TPM or HSM, and never has to exist as a file anywhere. Nothing else changes: to Okta, this is an ordinary private_key_jwt service app.
This design has two consequences that are worth understanding before you start:
Okta never sees the certificate. It receives one JWK containing a modulus and exponent, or a curve and coordinates. There is no chain, no CA, and no trust decision for Okta to make. A self-signed certificate is entirely normal here.
The JWK
kidis the certificate thumbprint. This is what ties the key registered in Okta to the certificate on the MIM server, and it's why replacing or renewing the certificate always means registering a new key in Okta.
Certificate requirements
The management agent checks all of this when it connects, so a mistake here surfaces the first time you retrieve the schema. The certificate must be:
Within its validity period
Backed by a private key the MIM Synchronization Service account can use
RSA of at least 2048 bits, or EC on P-256, P-384, or P-521
Permitted to sign, if it carries a Key Usage extension
Issuer, subject, SANs, and extended key usage are not checked. Both self-signed and CA-issued certificates work.
RSA keys sign with RS256. EC keys sign with ES256, ES384, or ES512, matching the curve.
Step 1: Choose the certificate store
This is the step that most often goes wrong, so it's worth taking the time to get it right.
The management agent looks for the thumbprint in two places, in this order:
CurrentUser\Myof the account running the MIM Synchronization ServiceLocalMachine\My
Find out which account runs the service:
Then pick a store:
You can start PowerShell as the service account
CurrentUser\My
None. A key created by that account is already usable by it.
Group managed service account, LocalSystem, or you do not have the password
LocalMachine\My
Grant the service account read access to the private key.
The cryptographic provider requires the machine store, or the key is shared
LocalMachine\My
Grant the service account read access to the private key.
Either way, the certificate needs to be installed on the MIM server that runs the management agent.
Step 2: Create the certificate
Skip to Step 3 if you already have a certificate that meets the requirements above.
Download OktaManagementAgentKeys.ps1 to the MIM server, review it, and load it:
New-OktaManagementAgentCertificate creates a non-exportable signing certificate and writes its public JWK. The output directory must already exist, and you'll need to add -Force to overwrite an existing output file.
Run whichever of the following applies, as the account whose store you chose in Step 1.
RSA
EC
P-384 and P-521 are also accepted.
TPM-backed
Windows exposes the TPM through the Microsoft Platform Crypto Provider. Name it with -Provider:
HSM
Create or enroll the certificate with the HSM vendor's own tooling, then treat it as an existing certificate and continue at Step 3.
The key must be usable by the MIM Synchronization Service account without any interactive steps, as there is nobody at the console during a scheduled run to authorize the use of the key.
Subject and expiry
The certificate is created with the subject CN=Lithnet Okta Management Agent and a validity of two years. Add -Subject and -NotAfter to any of the commands above to change either:
Whatever expiry you choose, record the date somewhere you'll see it before it arrives. Renewing the certificate involves work in both Okta and MIM.
If you used the LocalMachine store
Change -StoreLocation to LocalMachine in any of the commands above, and run PowerShell as an administrator. Then grant the service account access to the key:
Open
certlm.msc.Find the certificate under Personal > Certificates.
Right-click it, then All Tasks > Manage Private Keys.
Add the MIM Synchronization Service account with Read permission.
The certificate and its public JWK are ready. Go to Step 4.
Step 3: Export the public JWK
For a certificate you already have, load the tooling and convert it by thumbprint:
The thumbprint form searches CurrentUser\My then LocalMachine\My, the same order the management agent uses. If you run PowerShell as the service account, it will resolve to exactly the same certificate the connector will find.
If you are running as a different account, name the store instead so there is no ambiguity:
Only the public key is written. The private key stays in the certificate store or the hardware provider.
The result looks like this. It contains only public key material, so it's safe to email, paste into a ticket, or hand to your Okta administrator:
If you need a JWKS document instead, for a JWKS endpoint or the Okta management API, ConvertTo-OktaPublicJwks takes the same parameters and wraps the key in a keys array. Don't use this format when pasting the key into the Admin Console.
Step 4: Register the public key in Okta
Work through Creating the OAuth service app, pasting the contents of okta-ma-public.jwk.json at the public key step. Record the client ID.
Come back here once the app has its public key, scopes, and admin role.
Step 5: Configure MIM
On the management agent Connectivity page:
Set Authentication method to OAuth 2.0 (X.509 certificate).
Enter the app's client ID in OAuth client ID.
Enter the certificate thumbprint in Certificate thumbprint. Spaces are stripped, so pasting it out of the certificate dialog is fine.
Enter your Okta org URL in Tenant URL, for example
https://example.okta.com. Don't use the-adminhostname.Set the log file path and log level.
Save the page.

The Connectivity page shows the fields for all three authentication methods at once. With this method selected, only OAuth client ID, Certificate thumbprint, and Tenant URL are used. Leave API key and Private JWK file path empty.
Step 6: Retrieve the schema
Retrieve the management agent schema. This is the first point at which everything is exercised together: the certificate lookup, the private key, the OAuth token request, and the granted scopes. The object types and attribute directions MIM shows should match the scopes on the service app.
If it fails, see X.509 certificate troubleshooting.
Then continue with Creating the management agent.
Renewal and replacement
A renewed certificate normally has a new key pair, which means a new thumbprint, and therefore a new kid. You'll need to register a new public key in Okta and update the thumbprint in MIM. Key and certificate rotation shows you how to do this without an outage.
Last updated