Thirteen certificate signing requests are open at nextcloud/app-certificate-requests. This issue is what to do when they come back, so the knowledge does not live only in one session's scrollback.
Why these were needed
Every one of these apps was renamed. Nextcloud verifies that a signing certificate's CN equals the app id (lib/private/IntegrityCheck/Checker.php, Certificate is not valid for required scope). A certificate issued for openbuild cannot sign an app whose id is now buildiq.
🔴 The trap: signing does NOT check the CN. Only verification does. writeAppSignature() has no CN guard, so a mismatched certificate produces a release that goes green and an app that fails occ integrity:check-app on the administrator's side. Six of our apps are in exactly that state right now: integriq, filinq, dossiq, stackiq, larpinq and thematiq all release successfully while signing with their pre-rename certificates.
The other seven fail loudly at "Prepare signing credentials", which is the honest half of the same defect.
The requests
| PR |
App |
Was |
Old store entry |
| #1197 |
learniq |
scholiq |
published, removal requested |
| #1198 |
decidiq |
decidesk |
published, removal requested |
| #1199 |
buildiq |
openbuild |
published, removal requested |
| #1200 |
keepiq |
doriath |
published, removal requested |
| #1201 |
humaniq |
hrmq |
never published |
| #1202 |
versioniq |
app_versions |
published, removal requested |
| #1203 |
planninq |
planix |
never published |
| #1204 |
integriq |
openconnector |
published, removal requested |
| #1205 |
filinq |
docudesk |
published, removal requested |
| #1206 |
dossiq |
procest |
published, removal requested |
| #1207 |
stackiq |
softwarecatalog |
published, removal requested |
| #1208 |
larpinq |
larpingapp |
published, removal requested |
| #1209 |
thematiq |
nldesign |
published, removal requested |
(PR numbers are in nextcloud/app-certificate-requests.)
When a request is merged
Nextcloud commits <app>/<app>.crt next to the CSR. Per app:
-
Fetch the certificate
gh api repos/nextcloud/app-certificate-requests/contents/<app>/<app>.crt \
--jq .content | base64 -d > <app>.crt
-
Verify the CN before using it. This is the whole point of the exercise.
openssl x509 -in <app>.crt -noout -subject # must read CN = <app>
-
Verify it matches our private key. The keys live in the password vault, generated 2026-08-27, never committed anywhere.
openssl x509 -in <app>.crt -noout -modulus | md5sum
openssl rsa -in <app>.key -noout -modulus | md5sum # must be identical
-
Set both repository secrets on ConductionNL/<app>, Settings, Secrets and variables, Actions:
NEXTCLOUD_SIGNING_CERT = the whole .crt, including the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- lines
NEXTCLOUD_SIGNING_KEY = the matching .key from the vault
⚠️ Four repos (learniq, decidiq, buildiq, keepiq) already hold a CERT set on 2026-08-20 that fails the PEM-header check, so it was pasted without its header and footer. That is the failure mode to avoid.
-
Re-run the Release workflow on development and confirm "Prepare signing credentials" passes.
-
Verify the signature actually verifies. A green release is not proof, see the trap above.
occ integrity:check-app <app>
-
Remove the superseded App Store entry for the old id, for the eleven marked "published" above.
Definition of done
Reference
- Private keys: password vault, 13 entries, generated 2026-08-27, 4096-bit RSA,
CN = <new app id>
- The check that catches a bad paste lives in
.github/workflows/release.yml, step "Prepare signing credentials"
Thirteen certificate signing requests are open at nextcloud/app-certificate-requests. This issue is what to do when they come back, so the knowledge does not live only in one session's scrollback.
Why these were needed
Every one of these apps was renamed. Nextcloud verifies that a signing certificate's
CNequals the app id (lib/private/IntegrityCheck/Checker.php,Certificate is not valid for required scope). A certificate issued foropenbuildcannot sign an app whose id is nowbuildiq.🔴 The trap: signing does NOT check the CN. Only verification does.
writeAppSignature()has no CN guard, so a mismatched certificate produces a release that goes green and an app that failsocc integrity:check-appon the administrator's side. Six of our apps are in exactly that state right now:integriq,filinq,dossiq,stackiq,larpinqandthematiqall release successfully while signing with their pre-rename certificates.The other seven fail loudly at "Prepare signing credentials", which is the honest half of the same defect.
The requests
(PR numbers are in
nextcloud/app-certificate-requests.)When a request is merged
Nextcloud commits
<app>/<app>.crtnext to the CSR. Per app:Fetch the certificate
Verify the CN before using it. This is the whole point of the exercise.
Verify it matches our private key. The keys live in the password vault, generated 2026-08-27, never committed anywhere.
Set both repository secrets on
ConductionNL/<app>, Settings, Secrets and variables, Actions:NEXTCLOUD_SIGNING_CERT= the whole.crt, including the-----BEGIN CERTIFICATE-----and-----END CERTIFICATE-----linesNEXTCLOUD_SIGNING_KEY= the matching.keyfrom the vaultlearniq,decidiq,buildiq,keepiq) already hold a CERT set on 2026-08-20 that fails the PEM-header check, so it was pasted without its header and footer. That is the failure mode to avoid.Re-run the Release workflow on
developmentand confirm "Prepare signing credentials" passes.Verify the signature actually verifies. A green release is not proof, see the trap above.
Remove the superseded App Store entry for the old id, for the eleven marked "published" above.
Definition of done
developmentocc integrity:check-apppasses for all 13 on a real instancemydashremoved from the store:launchpadalready has its own correct certificate (CN = launchpad), so only the stale store entry remainsReference
CN = <new app id>.github/workflows/release.yml, step "Prepare signing credentials"