Skip to content

fix(security): close certificate, audit and enrollment gaps - #219

Merged
eniac111 merged 1 commit into
masterfrom
fix/security-limitations
Nov 12, 2026
Merged

eniac111 merged 1 commit into
masterfrom
fix/security-limitations

Conversation

@eniac111

Copy link
Copy Markdown
Member

Agent certificates:

  • The agent checks its certificate every 12 hours, not only at start, and renews it 30 days before expiry.
  • The policy port closes agent connections after at most 24 hours, so a renewed certificate is taken into use and an expired one cannot keep an old connection.
  • Renewal keeps the presented certificate valid until the node first opens a policy stream with the new one, then revokes it (reason "superseded by renewal"). A renewal retried with the previous certificate revokes the unused one; any older certificate is refused. Renewal no longer deletes the node's revocation records.
  • Revoking or decommissioning a node revokes its current and previous certificates.
  • Open policy streams re-check revocation and expiry every minute.
  • New migration 000048 adds nodes.previous_cert_serial.

Enrollment:

  • Enroll, KerberosEnroll and CreateEnrollmentToken are rate limited per client IP (BOR_ENROLL_RATE_LIMIT, default 60 per minute, 0 disables). The limiter moves to internal/ratelimit and is shared with the HTTP auth routes.
  • Kerberos enrollment refuses principals outside kerberos.realm (when set) and accepts only machine accounts (host/, $). The node name must belong to the principal.

Audit:

  • Forwarding headers (X-Forwarded-For, X-Real-IP) are believed only from BOR_TRUSTED_PROXIES / audit.trusted_proxies; X-Forwarded-For is walked from the right, skipping trusted hops.
  • BOR_AUDIT_ANONYMIZE_IPS now also applies to sign-in and sign-out.
  • bor-server --reset-mfa writes auth.mfa.reset audit records and refuses to reset MFA when it cannot write them.

Other:

  • CSRF and metrics bearer tokens are compared in constant time.
  • The agent resets its reconnect backoff after a stream that stayed up for at least a minute.

BREAKING CHANGE: a Kerberos-enrolled agent whose agent.client_id does not match its machine principal is now refused.

Agent certificates:
- The agent checks its certificate every 12 hours, not only at start,
  and renews it 30 days before expiry.
- The policy port closes agent connections after at most 24 hours, so a
  renewed certificate is taken into use and an expired one cannot keep
  an old connection.
- Renewal keeps the presented certificate valid until the node first
  opens a policy stream with the new one, then revokes it (reason
  "superseded by renewal"). A renewal retried with the previous
  certificate revokes the unused one; any older certificate is refused.
  Renewal no longer deletes the node's revocation records.
- Revoking or decommissioning a node revokes its current and previous
  certificates.
- Open policy streams re-check revocation and expiry every minute.
- New migration 000048 adds nodes.previous_cert_serial.

Enrollment:
- Enroll, KerberosEnroll and CreateEnrollmentToken are rate limited per
  client IP (BOR_ENROLL_RATE_LIMIT, default 60 per minute, 0 disables).
  The limiter moves to internal/ratelimit and is shared with the HTTP
  auth routes.
- Kerberos enrollment refuses principals outside kerberos.realm (when
  set) and accepts only machine accounts (host/<fqdn>, <NAME>$). The
  node name must belong to the principal.

Audit:
- Forwarding headers (X-Forwarded-For, X-Real-IP) are believed only from
  BOR_TRUSTED_PROXIES / audit.trusted_proxies; X-Forwarded-For is walked
  from the right, skipping trusted hops.
- BOR_AUDIT_ANONYMIZE_IPS now also applies to sign-in and sign-out.
- bor-server --reset-mfa writes auth.mfa.reset audit records and refuses
  to reset MFA when it cannot write them.

Other:
- CSRF and metrics bearer tokens are compared in constant time.
- The agent resets its reconnect backoff after a stream that stayed up
  for at least a minute.

BREAKING CHANGE: a Kerberos-enrolled agent whose agent.client_id does
not match its machine principal is now refused.
@eniac111
eniac111 merged commit 6e871ee into master Nov 12, 2026
28 checks passed
@eniac111
eniac111 deleted the fix/security-limitations branch November 12, 2026 16:04
@github-actions github-actions Bot locked and limited conversation to collaborators Nov 12, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant