SSO Setup
The local certificate authority
Everything on this tier is signed by one local root CA. That was a deliberate choice and it is the single biggest labour saver in the whole exercise.
Why reuse a CA instead of self-signing per service
A self-signed certificate per service means distributing and trusting each one separately, in every store that matters. On this tier that is at least four places (see trust stores). One CA means each store trusts the issuer once, and every certificate issued from it afterwards is trusted with no further work.
The CA already existed, created for the Keycloak identity provider:
keycloak-sso/certs/ca.crt Xcelerator Local Root CA, 10 year, to 2036
keycloak-sso/certs/ca.key private key, gitignored, never leaves the host
Critically, that CA was already trusted on the guest in both stores that matter: the Windows machine store, and the JDK truststore. So issuing the Teamcenter certificate from it meant the guest trusted the result immediately.
The server certificate
One leaf certificate covers every Teamcenter surface on the guest.
| Field | Value |
|---|---|
| Subject CN | siemensdc.xcelerator.local |
| Issuer | Xcelerator Local Root CA |
| Valid to | 2036 |
| Key | RSA 2048, SHA-256 |
Subject Alternative Names, which are what actually get matched:
DNS:siemensdc.xcelerator.local
DNS:siemensdc
DNS:SIEMENSDC
DNS:localhost
IP:192.168.222.100
IP:127.0.0.1
★ Browsers and the JVM ignore CN entirely and match on SAN. A name missing from that list fails validation no matter what the CN says. That is why the list is deliberately generous: this host is legitimately reached by short name, by FQDN and by IP.
⚠ siemensdc.xcelerator.local does not resolve on either the host or the
guest. It is in the SAN list so it validates if someone adds hosts entries, but
the name to actually use is siemensdc, which already resolves on both.
An early draft of this work proposed the FQDN before checking DNS; a JVM fetch
failing with ConnectException is what caught it.
Generating it
The generator is committed as keycloak-sso/scripts/gen-tc-cert.sh so the
certificate is reproducible rather than a one-off command in someone's history.
It emits PEM, because the Active Workspace gateway reads PEM text. See
Deployment Center for the PKCS12 conversion
that the Java side needs instead.
Verify any certificate you issue, rather than trusting the export:
openssl verify -CAfile certs/ca.crt certs/tc-server.crt
openssl x509 -noout -modulus -in certs/tc-server.crt | openssl md5
openssl rsa -noout -modulus -in certs/tc-server.key | openssl md5
The two moduli must be identical. If they differ, the key does not belong to the certificate and the server will fail to start with an error that names neither.