forked from mudler/LocalAI
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnats-auth-setup.sh
More file actions
executable file
·220 lines (186 loc) · 5.44 KB
/
Copy pathnats-auth-setup.sh
File metadata and controls
executable file
·220 lines (186 loc) · 5.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#!/usr/bin/env bash
# Generate NATS JWT authentication material and server configuration
# for LocalAI distributed mode.
#
# Requires: nsc (https://docs.nats.io/running-a-nats-service/configuration/securing_nats/auth_intro/nsc)
#
# Outputs:
# ./nats-keys/localai-nats.env
# ./nats-keys/localai-frontend.creds
# ./nats-keys/nats-auth.conf
# ./nats-keys/nats-server.conf
#
# Environment overrides:
# NATS_OPERATOR_NAME
# NATS_ACCOUNT_NAME
# NATS_SERVICE_USER
# NATS_KEYS_DIR
#
# LocalAI workers receive their own JWT and user seed when registering
# with the frontend.
set -euo pipefail
# Ensure newly created secret files are private by default.
umask 077
if ! command -v nsc >/dev/null 2>&1; then
echo "nsc is required. Install from https://github.com/nats-io/nsc/releases" >&2
exit 1
fi
OPERATOR="${NATS_OPERATOR_NAME:-localai-operator}"
ACCOUNT="${NATS_ACCOUNT_NAME:-localai}"
SYSTEM_ACCOUNT="${NATS_SYSTEM_ACCOUNT_NAME:-SYS}"
SERVICE_USER="${NATS_SERVICE_USER:-localai-frontend}"
OUTPUT_DIR="${NATS_KEYS_DIR:-./nats-keys}"
CREDS_FILE="$OUTPUT_DIR/${SERVICE_USER}.creds"
ENV_FILE="$OUTPUT_DIR/localai-nats.env"
AUTH_CONFIG_FILE="$OUTPUT_DIR/nats-auth.conf"
SERVER_CONFIG_FILE="$OUTPUT_DIR/nats-server.conf"
mkdir -p "$OUTPUT_DIR"
echo "Configuring NATS operator: $OPERATOR"
# Create the operator if it does not exist, otherwise select it.
if nsc select operator "$OPERATOR" >/dev/null 2>&1; then
echo "[ OK ] using existing operator '$OPERATOR'"
else
nsc add operator \
-n "$OPERATOR" \
--generate-signing-key
nsc select operator "$OPERATOR" >/dev/null
fi
# Create and assign the NATS system account.
if nsc describe account \
-n "$SYSTEM_ACCOUNT" >/dev/null 2>&1; then
echo "[ OK ] using existing system account '$SYSTEM_ACCOUNT'"
else
nsc add account -n "$SYSTEM_ACCOUNT"
fi
nsc edit operator \
--system-account "$SYSTEM_ACCOUNT"
# Create the LocalAI account if it does not exist.
if nsc describe account -n "$ACCOUNT" >/dev/null 2>&1; then
echo "[ OK ] using existing account '$ACCOUNT'"
else
nsc add account -n "$ACCOUNT"
fi
nsc select account "$ACCOUNT" >/dev/null
# Create the frontend service user if it does not exist.
if nsc describe user \
-n "$SERVICE_USER" \
--account "$ACCOUNT" >/dev/null 2>&1; then
echo "[ OK ] using existing user '$SERVICE_USER'"
else
nsc add user \
-n "$SERVICE_USER" \
--account "$ACCOUNT"
fi
# Frontend control-plane permissions.
nsc edit user \
-n "$SERVICE_USER" \
--account "$ACCOUNT" \
--allow-pub "nodes.>,gallery.>,agent.>,staging.>,state.>,jobs.>,mcp.>,cache.>,prefixcache.>,finetune.>" \
--allow-sub "nodes.>,gallery.>,agent.>,staging.>,state.>,jobs.>,mcp.>,cache.>,prefixcache.>,_INBOX.>"
# Generate a credentials file containing the frontend user JWT and seed.
rm -f "$CREDS_FILE"
nsc generate creds \
-a "$ACCOUNT" \
-n "$SERVICE_USER" \
-o "$CREDS_FILE"
# Extract the frontend JWT from the credentials file.
SERVICE_JWT="$(
awk '
/BEGIN NATS USER JWT/ {
capture = 1
next
}
/END NATS USER JWT/ {
capture = 0
}
capture
' "$CREDS_FILE" | tr -d '\r\n'
)"
# Extract the frontend user seed from the credentials file.
SERVICE_SEED="$(
awk '
/BEGIN USER NKEY SEED/ {
capture = 1
next
}
/END USER NKEY SEED/ {
capture = 0
}
capture
' "$CREDS_FILE" | tr -d '\r\n'
)"
# Retrieve the seed belonging to this exact account rather than taking
# the first account key found in the keystore.
ACCOUNT_SEED="$(
nsc list keys \
--account "$ACCOUNT" \
--accounts \
--show-seeds |
awk -F '|' -v expected="$ACCOUNT" '
function trim(value) {
gsub(/^[[:space:]]+|[[:space:]]+$/, "", value)
return value
}
NF >= 3 {
entity = trim($2)
seed = trim($3)
if (entity == expected && seed ~ /^SA[A-Z0-9]+$/) {
print seed
exit
}
}
'
)"
# Validate all extracted values before writing output files.
if [[ ! "$ACCOUNT_SEED" =~ ^SA[A-Z0-9]+$ ]]; then
echo "Unable to extract the account seed for '$ACCOUNT'." >&2
exit 1
fi
if [[ ! "$SERVICE_JWT" =~ ^eyJ ]]; then
echo "Unable to extract the service JWT from '$CREDS_FILE'." >&2
exit 1
fi
if [[ ! "$SERVICE_SEED" =~ ^SU[A-Z0-9]+$ ]]; then
echo "Unable to extract the service seed from '$CREDS_FILE'." >&2
exit 1
fi
# Generate the trusted operator and memory resolver configuration.
# This contains public operator/account JWT claims, not the private seeds.
nsc generate config \
--mem-resolver \
--config-file "$AUTH_CONFIG_FILE" \
--force
# Generate the primary NATS server configuration.
# The include path matches the Docker Compose mounts shown below.
cat >"$SERVER_CONFIG_FILE" <<'NATS_CONFIG'
server_name: localai-nats
port: 4222
http: 8222
jetstream {
store_dir: /data/jetstream
}
include nats-auth.conf
NATS_CONFIG
# Generate the environment file consumed by the LocalAI frontend.
cat >"$ENV_FILE" <<EOF
LOCALAI_NATS_ACCOUNT_SEED=$ACCOUNT_SEED
LOCALAI_NATS_SERVICE_JWT=$SERVICE_JWT
LOCALAI_NATS_SERVICE_SEED=$SERVICE_SEED
EOF
# The environment and credentials files contain private seeds.
chmod 600 "$CREDS_FILE" "$ENV_FILE"
# These contain server configuration and public JWT claims.
chmod 644 "$AUTH_CONFIG_FILE" "$SERVER_CONFIG_FILE"
echo
echo "=== LocalAI NATS JWT setup complete ==="
echo
echo "LocalAI environment: $ENV_FILE"
echo "Service credentials: $CREDS_FILE"
echo "NATS server config: $SERVER_CONFIG_FILE"
echo "NATS auth config: $AUTH_CONFIG_FILE"
echo
echo "Keep '$ENV_FILE' and '$CREDS_FILE' secret."
echo "Do not commit them to source control."
echo
echo "=== LocalAI NATS environment ==="
cat "$ENV_FILE"