ACME-compliant CA server (RFC8555)
  • Elixir 77.5%
  • Nix 11.1%
  • Gleam 8.5%
  • JavaScript 2.4%
  • Rust 0.5%
Find a file
2026-02-15 21:01:42 -08:00
.woodpecker reinit 2026-02-02 12:16:49 -08:00
assets homepage 2026-02-08 02:50:09 -08:00
config lego now works yayy!!! 2026-02-11 11:00:54 -08:00
lib ui: flatten pages to be more separatey 2026-02-15 20:56:42 -08:00
native/certdoll_i0 add i0 extension 2026-02-11 17:06:08 -08:00
nix dev: exclude deps.nix from formatters 2026-02-15 20:11:11 -08:00
priv set up SANs correctly 2026-02-11 12:57:40 -08:00
src/certdoll ui: flatten pages to be more separatey 2026-02-15 20:56:42 -08:00
test add i0 extension 2026-02-11 17:06:08 -08:00
.envrc nix: split dev and prod flake 2026-02-11 23:10:26 -08:00
.formatter.exs phoenix.. 2026-02-02 15:07:09 -08:00
.gitattributes remove deps.nix from repo stats 2026-02-11 23:49:09 -08:00
.gitignore add i0 extension 2026-02-11 17:06:08 -08:00
Cargo.lock add i0 extension 2026-02-11 17:06:08 -08:00
Cargo.toml add i0 extension 2026-02-11 17:06:08 -08:00
default.nix nix: sync flake 2026-02-11 23:23:37 -08:00
deps.nix mix: fix deps, again 2026-02-15 20:27:05 -08:00
flake.lock nix: sync flake 2026-02-11 23:23:37 -08:00
flake.nix mix: fix deps, again 2026-02-15 20:27:05 -08:00
gleam.toml add more pages 2026-02-08 05:31:46 -08:00
mix.exs mix: fix deps, again 2026-02-15 20:27:05 -08:00
mix.lock mix: fix deps, again 2026-02-15 20:27:05 -08:00
README.md update readme 2026-02-15 21:01:42 -08:00

certdoll

a (mostly) rfc8555 compliant ACME CA server written in elixir (primary logic) and gleam (just for the UI) with a tiny bit of rust for fun

developing

use nix; direnv supported

# due to gleam issues, this may need to be ran _a lot_ over and over
# run either one until it actually finishes
mix deps.get
mix gleam.deps.get

# run the web server
mix phx.server --open

# run tests (currently not productively testing)
mix test

deploying

{ inputs, ... }: {
  import = [
    inputs.certdoll.nixosModules.default
  ];

  services.certdoll = {
    enable = true;
    host = "acme.doll";
    port = 4000;
    user = "certdoll";

    dns_server = "10.100.69.69";

    ca_certificate = config.sops.secrets."acme.ca.doll.pem".path;
    ca_private_key = config.sops.secrets."acme.ca.doll.key".path;
    ca_private_key_password = config.sops.secrets."acme.ca.doll.key_".path;
    ca_chain = config.sops.secrets."acme.ca.doll.chain.pem".path;

    secret_key_base = config.sops.secrets."secret_key_base".path;
  };
}

progress

  • directory (/acme/directory)
  • nonce (/acme/nonce/new)
    • wtf is this for actually?
    • oh right, security....
  • orders
    • new order (/acme/order/new)
    • get order (/acme/order/<order_id>)
  • accounts
    • creation (/acme/account/new)
    • get account (/acme/account/<account_id>)
    • lookup by key on new account
  • authz (/acme/authz/<authz_id>)
    • dns identifier authz
      • http-01 (/acme/authz/<authz_id>/chall/http-01)
      • dns-01 (/acme/authz/<authz_id>/chall/dns-01)
        • dns-over-https
        • dns-over-udp
      • tls-alpn-01 (/acme/authz/<authz_id>/chall/tls-alpn-01)
      • dns-account-01
      • dns-persist-01
    • ip identifier authz
      • http-01 (/acme/authz/<authz_id/chall/http-01)
        • BUG: can't do http-01 against IPv6 IPs
      • tls-alpn-01 (/acme/authz/<authz_id>/chall/tls-alpn-01)
  • certificate (/acme/cert/<cert_id>)
  • certificate revokation
    • CRL distribution
    • revoke-cert (/acme/revoke-cert)
  • key change (/acme/key-change)
  • caa enforcement
  • web UI
    • homepage with docs (/)
    • something to fill the terms link (/terms)
    • certificate list (/certificates)
    • identifier list (/identifiers)