Files
2026-09-18 19:45:17 -07:00

2.1 KiB
Raw Permalink Blame History

Security

Private key on the server

Design B generates the user private key in the portal:

  • Created in RAM on POST /download
  • Exported into an identity PKCS#12 (still RAM)
  • Embedded in the plist, which is then CMS-signed
  • Returned in the HTTP response
  • Not written to disk; no cache of keys or P12 passwords

Anyone who can download a profile for a user obtains that user’s private key. Protect the app like an RA:

  • OIDC on every download
  • Optional LDAP_REQUIRED_GROUP
  • HTTPS only in production (SESSION_HTTPS_ONLY, reverse-proxy TLS)
  • Restrict who can reach the portal (VPN, SSO group, IP allow list)

Do not use this design for keys that must be device-bound.

Logging

The portal logs UPN and SID at info when a profile is issued. It does not log:

  • Identity P12 bytes or passwords
  • Profile-signing P12 passwords
  • OIDC client secrets, LDAP bind passwords, certsrv passwords
  • Raw CSR PEM at info (avoid debug logging in production)

Session cookie: HttpOnly, SameSite=lax, Secure when SESSION_HTTPS_ONLY is true.

Who can enroll

  1. Must complete OIDC (valid session).
  2. Must match exactly one LDAP user.
  3. If LDAP_REQUIRED_GROUP is set, must be a member (nested groups allowed).
  4. The service account, not the user, must have Enroll on the template. A signed-in user cannot enroll a template the portal account cannot enroll.

There is no Enrollment Agent. A caller cannot request a cert for a different SID than LDAP returned for their username.

CA trust

Prefer CERTSRV_VERIFY_TLS=true and LDAP_VERIFY_TLS=true. Disabling TLS verification allows credential theft on the path to certsrv (NTLM) and LDAP.

OpenAPI

Leave DOCS_ENABLED=false in production so /docs is not public.

Threat notes

Issue Mitigation
Stolen session cookie Short IdP session, HTTPS, Secure cookies
Stolen signing P12 Filesystem permissions / secret store; rotate
Template too powerful Dedicated Wi-Fi user template, not a smartcard/admin template
certsrv HTML change Parser fails closed (unknown page = error), fixtures in tests
SSRF-ish CA URL CERTSRV_URL is config, not user input