1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8 cfg = config.services.lk-jwt-service;
9in
10{
11 meta.maintainers = [ lib.maintainers.quadradical ];
12 options.services.lk-jwt-service = {
13 enable = lib.mkEnableOption "lk-jwt-service";
14 package = lib.mkPackageOption pkgs "lk-jwt-service" { };
15
16 livekitUrl = lib.mkOption {
17 type = lib.types.strMatching "^wss?://.*";
18 example = "wss://example.com/livekit/sfu";
19 description = ''
20 The public websocket URL for livekit.
21 The proto needs to be either `wss://` (recommended) or `ws://` (insecure).
22 '';
23 };
24
25 keyFile = lib.mkOption {
26 type = lib.types.path;
27 description = ''
28 Path to a file containing the credential mapping (`<keyname>: <secret>`) to access LiveKit.
29
30 Example:
31 `lk-jwt-service: f6lQGaHtM5HfgZjIcec3cOCRfiDqIine4CpZZnqdT5cE`
32
33 For more information, see <https://github.com/element-hq/lk-jwt-service#configuration>.
34 '';
35 };
36
37 port = lib.mkOption {
38 type = lib.types.port;
39 default = 8080;
40 description = "Port that lk-jwt-service should listen on.";
41 };
42 };
43
44 config = lib.mkIf cfg.enable {
45 systemd.services.lk-jwt-service = {
46 description = "Minimal service to issue LiveKit JWTs for MatrixRTC";
47 documentation = [ "https://github.com/element-hq/lk-jwt-service" ];
48 wantedBy = [ "multi-user.target" ];
49 wants = [ "network-online.target" ];
50 after = [ "network-online.target" ];
51 environment = {
52 LIVEKIT_URL = cfg.livekitUrl;
53 LIVEKIT_JWT_PORT = toString cfg.port;
54 LIVEKIT_KEY_FILE = "/run/credentials/lk-jwt-service.service/livekit-secrets";
55 };
56
57 serviceConfig = {
58 LoadCredential = [ "livekit-secrets:${cfg.keyFile}" ];
59 ExecStart = lib.getExe cfg.package;
60 DynamicUser = true;
61 LockPersonality = true;
62 MemoryDenyWriteExecute = true;
63 ProtectClock = true;
64 ProtectControlGroups = true;
65 ProtectHostname = true;
66 ProtectKernelLogs = true;
67 ProtectKernelModules = true;
68 ProtectKernelTunables = true;
69 PrivateDevices = true;
70 PrivateMounts = true;
71 PrivateUsers = true;
72 RestrictAddressFamilies = [
73 "AF_INET"
74 "AF_INET6"
75 ];
76 RestrictNamespaces = true;
77 RestrictRealtime = true;
78 ProtectHome = true;
79 SystemCallArchitectures = "native";
80 SystemCallFilter = [
81 "@system-service"
82 "~@privileged"
83 "~@resources"
84 ];
85 Restart = "on-failure";
86 RestartSec = 5;
87 UMask = "077";
88 };
89 };
90 };
91}