mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-10-02 04:50:21 +00:00
nixos/cliproxyapi: use v8 config layout
Signed-off-by: Anish Pallati <i@anish.land>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# CLIProxyAPI {#module-services-cliproxyapi}
|
||||
|
||||
[CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI) exposes OAuth-based subscription CLIs (Claude Code, Codex, Gemini, Qwen, Grok, Antigravity) behind OpenAI/Gemini/Anthropic-compatible HTTP APIs.
|
||||
[CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI) exposes OAuth-based subscription CLIs (Claude Code, Codex, Grok, Antigravity, Kimi, Devin, Meta) behind OpenAI/Gemini/Anthropic-compatible HTTP APIs.
|
||||
|
||||
Enable it with:
|
||||
|
||||
@@ -10,11 +10,11 @@ Enable it with:
|
||||
}
|
||||
```
|
||||
|
||||
The service runs as a dedicated `cliproxyapi` user and keeps its configuration and OAuth tokens under `/var/lib/cliproxyapi`.
|
||||
The service runs as a dedicated `cliproxyapi` user and keeps its configuration and OAuth tokens under `/var/lib/cliproxyapi`. The configuration file is regenerated from [](#opt-services.cliproxyapi.settings) at startup, which overwrites any changes made through the management API.
|
||||
|
||||
## Authentication {#module-services-cliproxyapi-authentication}
|
||||
|
||||
Provider logins use OAuth and must land in the service's `auth-dir` (`/var/lib/cliproxyapi`), which is owned by the `cliproxyapi` user. Either of the approaches below writes the token with the correct ownership, and the running service picks it up without a restart.
|
||||
Provider logins use OAuth and must land in the service's `oauth.auth-dir` (`/var/lib/cliproxyapi`), which is owned by the `cliproxyapi` user. Either of the approaches below writes the token with the correct ownership, and the running service picks it up without a restart.
|
||||
|
||||
### Management API {#module-services-cliproxyapi-authentication-management-api}
|
||||
|
||||
@@ -22,19 +22,31 @@ Set a management key in [](#opt-services.cliproxyapi.settings):
|
||||
|
||||
```nix
|
||||
{
|
||||
services.cliproxyapi.settings.remote-management.secret-key._secret =
|
||||
"/run/secrets/cliproxyapi-mgmt-key";
|
||||
services.cliproxyapi.settings.management.secret-key._secret = "/run/secrets/cliproxyapi-mgmt-key";
|
||||
}
|
||||
```
|
||||
|
||||
Then request an authentication URL for the desired provider and open it in a browser:
|
||||
Request a login URL and open it in a browser:
|
||||
|
||||
```bash
|
||||
curl -H "Authorization: Bearer <management-key>" \
|
||||
http://127.0.0.1:8317/v0/management/anthropic-auth-url
|
||||
"http://127.0.0.1:8317/v8/management/oauth/auth-url?provider=claude"
|
||||
```
|
||||
|
||||
The daemon completes the OAuth flow itself and stores the token in its `auth-dir`. Authentication endpoints are available for the `anthropic`, `codex`, `xai`, `antigravity`, and `kimi` providers.
|
||||
Other values for `provider` are `codex`, `antigravity`, `kimi`, `kimi-ai`, `xai`, `devin` and `meta`. `kimi`, `kimi-ai`, `xai` and `meta` use a device code, so the login finishes once it is approved in the browser.
|
||||
|
||||
For `claude`, `codex` and `antigravity`, the browser ends up on a `localhost` page that fails to load. Send that URL to the daemon to finish the login:
|
||||
|
||||
```bash
|
||||
curl -H "Authorization: Bearer <management-key>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"redirect_url": "<url>"}' \
|
||||
http://127.0.0.1:8317/v8/management/oauth/callback
|
||||
```
|
||||
|
||||
Alternatively, add `is_webui=true` to the login URL request, and the daemon will listen on the callback port and finish the login itself.
|
||||
|
||||
To check on a login, query `/v8/management/oauth/status?state=<state>` with the `state` from the login URL response. It returns `wait` while the login is pending, `ok` once the token is saved and `error` if it failed.
|
||||
|
||||
### Command-line login {#module-services-cliproxyapi-authentication-cli}
|
||||
|
||||
@@ -52,4 +64,4 @@ Then run the login as the service user, pointing at the managed configuration:
|
||||
sudo -u cliproxyapi cliproxyapi -config /var/lib/cliproxyapi/config.yaml --claude-login
|
||||
```
|
||||
|
||||
Other providers use their matching flags, for example `--codex-login` or `--xai-login`. On a headless host, pass `-no-browser` to print the OAuth URL instead of launching a browser.
|
||||
Other providers have their own flags, such as `--codex-login` or `--xai-login`; see `cliproxyapi -help`. On a headless host, add `-no-browser` to print the login URL. The Claude, Codex, Antigravity and Devin logins then ask you to paste the `localhost` URL you were redirected to.
|
||||
|
||||
@@ -10,14 +10,9 @@ let
|
||||
format = pkgs.formats.yaml { };
|
||||
stateDir = "/var/lib/cliproxyapi";
|
||||
configPath = "${stateDir}/config.yaml";
|
||||
settings = {
|
||||
auth-dir = stateDir;
|
||||
}
|
||||
// cfg.settings;
|
||||
secretsReplacement = utils.genJqSecretsReplacement {
|
||||
loadCredential = true;
|
||||
} settings configPath;
|
||||
port = cfg.settings.port or 8317;
|
||||
} cfg.settings configPath;
|
||||
in
|
||||
{
|
||||
options.services.cliproxyapi = {
|
||||
@@ -26,14 +21,30 @@ in
|
||||
package = lib.mkPackageOption pkgs "cliproxyapi" { };
|
||||
|
||||
settings = lib.mkOption {
|
||||
type = format.type;
|
||||
type = lib.types.submodule {
|
||||
freeformType = format.type;
|
||||
options = {
|
||||
server.port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 8317;
|
||||
description = "Port on which CLIProxyAPI listens.";
|
||||
};
|
||||
oauth.auth-dir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = stateDir;
|
||||
description = "Directory where OAuth tokens are stored.";
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
host = "127.0.0.1";
|
||||
port = 8317;
|
||||
api-keys = [ { _secret = "/run/secrets/cliproxyapi-api-key"; } ];
|
||||
remote-management.secret-key._secret = "/run/secrets/cliproxyapi-management-key";
|
||||
server = {
|
||||
host = "127.0.0.1";
|
||||
port = 8317;
|
||||
};
|
||||
access.api-keys = [ { _secret = "/run/secrets/cliproxyapi-api-key"; } ];
|
||||
management.secret-key._secret = "/run/secrets/cliproxyapi-management-key";
|
||||
}
|
||||
'';
|
||||
description = ''
|
||||
@@ -54,7 +65,7 @@ in
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Whether to open the firewall for the specified port.";
|
||||
description = "Whether to open the firewall for {option}`services.cliproxyapi.settings.server.port`.";
|
||||
};
|
||||
|
||||
user = lib.mkOption {
|
||||
@@ -142,7 +153,7 @@ in
|
||||
};
|
||||
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [ port ];
|
||||
allowedTCPPorts = [ cfg.settings.server.port ];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -10,9 +10,11 @@
|
||||
services.cliproxyapi = {
|
||||
enable = true;
|
||||
settings = {
|
||||
host = "127.0.0.1";
|
||||
port = 8317;
|
||||
api-keys = [ { _secret = "/etc/cliproxyapi-api-key"; } ];
|
||||
server = {
|
||||
host = "127.0.0.1";
|
||||
port = 8317;
|
||||
};
|
||||
access.api-keys = [ { _secret = "/etc/cliproxyapi-api-key"; } ];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user