Files
jarl/internal/model/certificate.go
T
adamandClaude Opus 5.5 b4bb99b482 Certificate export, missing PTR list, simpler "Used for"
- Certificates can be exported for use outside Jarl: Export… on the
  Certificates page (download or copy), jarl cert export, and
  GET /certificates/{name}/pem?part=fullchain|cert|key|bundle.
  Administrators only; key exports are audited.
- A reverse zone's missing-PTR banner lists the addresses and names
  (ptr_missing_list in the zone API).
- "Used for" shows DoT/DoH for named, and "not used by Jarl" instead of
  "nothing yet".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 16:07:26 +01:00

73 lines
2.9 KiB
Go

package model
import (
"slices"
"time"
)
// Certificate sources.
const (
CertSourceACME = "acme" // Jarl obtains and renews it (docs/certificates.md)
CertSourceFile = "file" // you renew it; Jarl reads it from cert_file and key_file
)
// Certificate uses.
const (
CertUseWeb = "web" // jarld's own HTTPS
CertUseDNS = "dns" // written where named can read it, for DNS over TLS/HTTPS
)
// Challenge routes: where Jarl publishes the DNS-01 challenge.
const (
ChallengeAuto = "auto" // decided at every issue from the domain's public name servers
ChallengeJarl = "jarl" // in a zone Jarl serves (following a CNAME on _acme-challenge)
ChallengePorkbun = "porkbun" // through Porkbun's DNS API
)
// Certificate is a TLS certificate Jarl manages. Certificates are not
// named configuration: they are kept outside changesets, like users.
type Certificate struct {
ID int64 `json:"id"`
Name string `json:"name"`
Source string `json:"source"`
Domains []string `json:"domains"` // acme: the names to ask for; file: the names in the certificate
CertFile string `json:"cert_file,omitempty"` // file source
KeyFile string `json:"key_file,omitempty"` // file source
Uses []string `json:"uses"`
Challenge string `json:"challenge,omitempty"` // acme source
KeyType string `json:"key_type,omitempty"` // acme source: ec256, ec384, rsa2048, rsa3072, rsa4096
Comment string `json:"comment"`
// The current certificate: acme source only (a file source's is read
// from its files). The key leaves the server only through the
// administrators' export (GET /certificates/{name}/pem), audited.
CertPEM string `json:"-"`
KeyPEM string `json:"-"`
// What the current certificate says (both sources).
Names []string `json:"names,omitempty"` // the names in it
NotBefore *time.Time `json:"not_before,omitempty"`
NotAfter *time.Time `json:"not_after,omitempty"`
Issuer string `json:"issuer,omitempty"`
Serial string `json:"serial,omitempty"`
// Renewal (acme source). RenewAt is the CA's suggested time (ARI) or,
// without one, two thirds into the certificate's lifetime.
RenewAt *time.Time `json:"renew_at,omitempty"`
ARICheckedAt *time.Time `json:"-"`
LastAttempt *time.Time `json:"last_attempt,omitempty"`
LastSuccess *time.Time `json:"last_success,omitempty"`
LastError string `json:"last_error,omitempty"`
Failures int `json:"failures,omitempty"`
// LastRoutes says where the challenges went the last time ("adbraun.lol: porkbun").
LastRoutes []string `json:"last_routes,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
CreatedBy string `json:"created_by"`
UpdatedBy string `json:"updated_by"`
}
// HasUse reports whether c is used for use.
func (c *Certificate) HasUse(use string) bool { return slices.Contains(c.Uses, use) }