Skills
Polarion Https And Rest
Skill
polarion-https-and-rest. Put Polarion 2606 on HTTPS, move base.url, run the index rebuild it forces, redirect HTTP, and enable the REST API. Covers serving TLS on a non-standard port when 443 is taken, the JDK truststore Polarion needs to call its own base URL, the reindex script whose real behaviour differs from the documentation so a correct rebuild reads as "never ran", the Apache rewrite rule whose guard silently stops guarding when you add a second rule, and the REST API status code that means success. Use for Polarion SSL, base.url or repo changes, "do I need a reindex", HTTP to HTTPS redirects, enabling the REST API or Swagger UI, and any Polarion change that has to be coordinated with a Teamcenter SSO Application Registry entry.
Provenance is marked throughout. EXERCISED came back from a real run on this estate
(Polarion 2606 at D:\Polarion on MARTINI-GAMING, bundled Apache 2.4.67, JDK 21, TcSS SSO on
siemensdc:8093, 2026-08-19). DERIVED was read out of the shipped 2606 documentation and has
not been run.
Everything below assumes D:\Polarion is ACL'd to SYSTEM and Administrators, so every read and
write needs elevation. ⚠ An unelevated grep under that tree returns nothing rather than an
error, which reads exactly like "the setting is absent". Confirm you can read the file before
concluding anything from an empty result.
1. Order of operations
Do these in order. Steps 2 and 3 are deliberately split, because step 3 is the irreversible-ish half.
- Issue a certificate.
- Serve HTTPS and prove it, without touching Polarion's identity.
- Move
base.urlandrepo, import the CA into Polarion's JDK, restart, reindex. - Redirect HTTP.
- Enable the REST API if wanted.
Splitting 2 from 3 matters: step 3 forces a full index rebuild and rewrites how Polarion refers to itself. Do not force that onto an endpoint you have not yet seen serve.
2. Choosing a port
443 is not always free. EXERCISED here: wslrelay (Docker Desktop's Kubernetes ingress) holds
0.0.0.0:443, so Polarion went to 4443.
netstat -ano | grep -E ":443\b|:4443\b"
A non-standard port propagates further than expected. It must appear in base.url, in repo, in
ServerName, and in any external registration such as a Teamcenter SSO Application Registry entry.
Decide it once, up front.
3. Certificate
Issue for the exact hostname Polarion is reached by, with SANs covering every name and address that will be used:
CN = martini-gaming
subjectAltName = DNS:martini-gaming, DNS:localhost, IP:127.0.0.1, IP:192.168.222.1
extendedKeyUsage = serverAuth
basicConstraints = CA:FALSE
Sign with a CA the host already trusts. EXERCISED: CN=Xcelerator Local Root CA, already in
LocalMachine\Root, which also signs Keycloak.
4. Apache: serve HTTPS
DERIVED from "Configure SSL" (topic xid1550497), EXERCISED end to end.
In D:\Polarion\bundled\apache\conf\httpd.conf: uncomment LoadModule ssl_module and
Include conf/extra/httpd-ssl.conf. In conf\extra\httpd-ssl.conf: set Listen, the
<VirtualHost _default_:PORT>, ServerName host:PORT, and the certificate paths.
⚠ The stock httpd-ssl.conf ships ONE active certificate directive plus TWO commented
alternates (DSA and ECC). A pattern like ^#?\s*SSLCertificateFile\s matches all three and
activates all three. Apache passes httpd -t and serves correctly because the duplicates are
identical and the last wins, so nothing looks wrong. The damage is to the next reader, who edits the
first of three and sees no effect. Keep the first match, drop the rest.
⚠ Leave SSLSessionCacheTimeout alone (the guide says so), and leave Listen 80 alone at this
stage.
Always validate before restarting, and roll back if invalid:
& "D:\Polarion\bundled\apache\bin\httpd.exe" -t # exit 0 and "Syntax OK"
httpd -S is the authority on what is actually bound:
*:4443 martini-gaming (D:/Polarion/bundled/apache/conf/extra/httpd-ssl.conf:121)
Verify with a control. A plain fetch proves reachability, not trust:
curl.exe -sS --ssl-no-revoke -o /dev/null -w "%{http_code} %{ssl_verify_result}\n" https://host:4443/polarion/
curl.exe -sS --ssl-no-revoke --cacert <a-DIFFERENT-ca.crt> https://host:4443/polarion/ # MUST fail
The wrong-CA run failing with CERT_TRUST_IS_PARTIAL_CHAIN while the default run passes is what
proves validation is switched on. ⚠ Windows curl.exe uses Schannel and may refuse with
CRYPT_E_NO_REVOCATION_CHECK because a local CA publishes no CRL or OCSP. That is strictness, not a
chain failure; --ssl-no-revoke is the right response and browsers are lenient here.
⚠ A 200 is not proof Polarion is alive. Fetch something only the application can answer:
/polarion/authentication.xsd returning 200, or the body being Polarion's real login form.
5. base.url, repo, and the JDK truststore
DERIVED from "Configure SSL" (topic xid1550497) and "Additional SSL settings for Linux"
(xid1550496), EXERCISED.
In D:\Polarion\polarion\configuration\polarion.properties:
base.url=https://martini-gaming:4443
repo=https://martini-gaming:4443/repo/
⚠ Only rewrite repo if it is currently an http:// URL. A file:/// repo is a local path, and
converting it is a different change entirely.
⚠⚠ The CA must go into Polarion's own JDK truststore, and this is not optional. The guide:
"Unless you have disabled the Resource Traceability feature, which is enabled by default, you will
have to import a certificate into your Polarion Java TrustStore." Polarion calls its own
base.url over HTTPS, so its JVM has to trust the certificate it is serving.
$jdk = 'D:\Java\jdk-21.0.12+8'
& "$jdk\bin\keytool.exe" -importcert -noprompt -trustcacerts -cacerts -storepass changeit `
-alias xcelerator-local-root-ca -file ca.crt
Prove it with an A/B control, not by re-reading the store. Run a tiny Java probe against the new
URL twice: once with the live cacerts (must PASS) and once with -Djavax.net.ssl.trustStore set
to the pre-import backup (must FAIL). EXERCISED:
A (live cacerts, post-import) : PASS https://martini-gaming:4443/polarion/ HTTP 200
B (pre-import backup store) : FAIL SSLHandshakeException ... PKIX path building failed
If B also passes, the trust predates your import and the A/B has proved nothing.
The documented failure mode for this whole step is svn: E175002 ... SSLProtocolException: handshake alert: unrecognized_name, fixed by setting ServerName in the SSL vhost. Grep the logs for
E175002, SSLHandshakeException and PKIX afterwards; their absence is part of the evidence.
6. ⚠⚠ The reindex, and why a correct one looks like it never ran
DERIVED from "Index and Reindex" (topic xid1552831); the correction below is EXERCISED.
Changing base.url requires a full index rebuild. The Polarion service must be stopped
first. Run it in its own window and do not interrupt it:
D:\Polarion\polarion\reindex.bat
⚠⚠ The documentation is wrong about the folder name, and believing it produces a false negative.
The docs say the script renames data\workspace\polarion-data to polarion-data.saved. The
shipped 2606 script actually says:
if exist "%WORKSPACE%\polarion-data.backup" goto ERROR
rename "%WORKSPACE%\polarion-data" polarion-data.backup
.backup, not .saved. Checking for .saved, finding nothing, and reporting "the rebuild never
started" is a mistake this skill exists to prevent. Read the script, not the manual.
Note the guard on line 1: if polarion-data.backup already exists the script prints an error and
does nothing. A leftover backup from a previous rebuild silently blocks the next one.
How to actually verify a rebuild happened. The startup log names the mode:
log4j-<stamp>.log:31 INFO com.polarion.platform.startup - Server start mode: reindex
log4j-<stamp>.log:1070 INFO ... - reindexing 1134 existing objects and 1 deleted objects
A normal start reindexes 1 object. A rebuild reindexes the repository. That contrast is the proof, not the folder name.
⚠ On a small demo repository the rebuild finishes in seconds, not the "minutes to hours" the guide warns of. A fast completion is not evidence of failure.
⚠ Do not measure the logs by reported file size. EXERCISED: a listing reported
log4j-startup-*.log as 0 bytes when it held 13,616, and ReadAllText returned ~210 characters of a
file whose line 1526 read fine. The files are open and being written. Select-String is the only
instrument that gave true answers.
7. Redirect HTTP to HTTPS
DERIVED requirement from "Configure SSL": "Any attempt to access Polarion using HTTP must be
automatically redirected to HTTPS." The guide's own suggestion is to comment out Listen 80.
Prefer a redirect over closing the port. Killing 80 turns every stale bookmark into a bare connection-refused with no explanation, and removes the only unencrypted way to diagnose the box.
<IfModule rewrite_module>
RewriteEngine On
RewriteCond %{SERVER_PORT} =80
RewriteRule ^ https://martini-gaming:4443%{REQUEST_URI} [R=302,L]
</IfModule>
⚠⚠ A RewriteCond binds ONLY to the RewriteRule immediately following it. Insert a second
rule between them and the later rule becomes unguarded, applies on every port including the TLS
vhost, and redirects HTTPS to itself. EXERCISED, and it took the site down:
https://host:4443/polarion/ returned 302 to itself, 50 hops. If you need two rules, repeat the
RewriteCond before each one.
⚠ Prefer 302 over 301 while a configuration is still settling. A permanent redirect is cached hard by browsers and survives a rollback, so reverting leaves every browser that touched it still jumping to the old target with no way to tell them otherwise.
⚠ ^/?(.*) does not match the bare root path in this configuration: every other path redirects
and http://host/ returns 404. ^ with %{REQUEST_URI} has no empty-path edge case. Note that on
a stock install the bare root 404s anyway (DocumentRoot htdocs has no index), so this may not be
worth chasing.
Verify path AND query survive, and control that the TLS port is unaffected:
/polarion/?foo=bar&baz=1 -> 302 https://host:4443/polarion/?foo=bar&baz=1
https://host:4443/polarion/ -> 200 with NO redirect <- the control that matters
8. Enable the REST API
DERIVED from the REST API User Guide, "Enable REST API" (topic xid2137943), EXERCISED.
Both are system-level properties in polarion.properties, both off by default, both need a
restart:
com.siemens.polarion.rest.enabled=true
com.siemens.polarion.rest.swaggerUi.enabled=true
swaggerUi has no effect unless rest.enabled is true. The guide notes they default off "to give
you more control over security", because Swagger exposes an interactive console. Reasonable on a
demo tier, a decision to make consciously elsewhere.
API root and Swagger UI are the same URL: https://host:4443/polarion/rest/v1. Response links are
built from base.url.
⚠⚠ The success signal is a 401, and the same 503 means two different things. From "Check REST
API availability" (topic xid2138066):
| Response | Meaning |
|---|---|
| 401 Unauthorized | REST API is enabled. This is success. |
| 503 with a JSON body | Polarion is up, REST API disabled |
| 503 with an Apache HTML page | Polarion itself is down or still starting |
EXERCISED, and it nearly produced a false failure report: 90 seconds after the restart the endpoint
returned 503 with an HTML body and /polarion/ was also 503, because the JVM was still starting.
Polling to app=200 gave rest=401. Reading only the status code would have reported failure just
before it succeeded. Take the baseline before the change so you have a difference to judge:
before: 503 {"errors":[{"status":"503","title":"Service Unavailable"}]}
after : 401 {"errors":[{"status":"401","title":"Unauthorized","detail":"No access token"}]}
Authentication is separate: PAT, JWT, or a Teamcenter SSO (TCSSO) token. PATs are generated per user in the Polarion UI.
9. Coordinating with Teamcenter SSO
If Polarion authenticates through TcSS, moving to HTTPS breaks SSO until the Application Registry
entry moves with it. The registered root URL must become https://host:4443.
⚠ Host root only. No trailing slash, no /polarion. TcSS appends TCSSORURI=/polarion/ itself,
so any path in the registry value produces a doubled /polarion/polarion/ and the return leg 404s.
The registry is checked on the return leg only, so a clean outbound redirect proves nothing. See
the polarion-authentication skill.
Sequence it deliberately: Polarion is down for the reindex anyway, which is the natural window.
10. The verification bar
A running service proves nothing. For this family of changes, accept only:
- HTTPS returning 200 on something only Polarion can serve, with a wrong-CA control proving trust is real;
- the JVM A/B proving the truststore import is what granted trust;
Server start mode: reindexplus an object count far above 1;- the redirect preserving path and query, with a control showing the TLS port does not redirect;
- REST returning 401 with a JSON body;
- and finally a real user logging in, which is the only check that exercises HTTPS,
base.url, the truststore, the redirect and the SSO registry entry together.
Item 6 is the one that cannot be faked. Everything above it can pass while the system is unusable.
Generated from skills/polarion-https-and-rest/SKILL.md in the tc-automation-skills library, which is the canonical copy and also serves as the agent skill set for Teamcenter work.