- Remove hardcoded client secret from init container - Reference secret from paperless-ai-config (SOPS-encrypted) - Init container reads LLM_AUTH_CLIENT_SECRET env var - Secret key must be added to k8s/argocd/secrets/paperless-ai-secrets.enc.yaml by someone with SOPS/age key access This removes the plaintext secret from commit history and future deployments will source it securely from the encrypted Secret.
115 lines
3.9 KiB
YAML
115 lines
3.9 KiB
YAML
# Secret paperless-ai-config managed via SOPS (argocd/secrets/paperless-ai-secrets.enc.yaml)
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: paperless-ai
|
|
namespace: paperless
|
|
labels:
|
|
app.kubernetes.io/name: paperless-ai
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app.kubernetes.io/name: paperless-ai
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app.kubernetes.io/name: paperless-ai
|
|
spec:
|
|
tolerations:
|
|
- key: node-role.kubernetes.io/control-plane
|
|
operator: Exists
|
|
effect: NoSchedule
|
|
volumes:
|
|
- name: paperless-ai-data
|
|
persistentVolumeClaim:
|
|
claimName: paperless-ai-data
|
|
initContainers:
|
|
- name: fetch-llm-token
|
|
image: curlimages/curl:8.12.0
|
|
command:
|
|
- sh
|
|
- -c
|
|
- |
|
|
set -e
|
|
echo "[init] Fetching JWT token from Authentik for paperless-ai-agent..."
|
|
|
|
# Get JWT token via client_credentials grant
|
|
# Client secret sourced from environment (injected from paperless-ai-config Secret)
|
|
TOKEN_RESPONSE=$(curl -s -X POST https://authentik.riotpiao.com/application/o/token/ \
|
|
-d "grant_type=client_credentials" \
|
|
-d "client_id=paperless-ai-agent" \
|
|
-d "client_secret=${LLM_AUTH_CLIENT_SECRET}" \
|
|
-d "scope=openid llm:inference" 2>/dev/null)
|
|
|
|
# Extract token
|
|
TOKEN=$(echo "$TOKEN_RESPONSE" | grep -o '"access_token":"[^"]*' | cut -d'"' -f4)
|
|
|
|
if [ -z "$TOKEN" ]; then
|
|
echo "[error] Failed to get token. Response: $TOKEN_RESPONSE"
|
|
exit 1
|
|
fi
|
|
|
|
# Store token in file for main container to read
|
|
mkdir -p /data
|
|
echo "$TOKEN" > /data/llm_token.txt
|
|
echo "[init] Token fetched and stored successfully"
|
|
env:
|
|
- name: LLM_AUTH_CLIENT_SECRET
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: paperless-ai-config
|
|
key: LLM_AUTH_CLIENT_SECRET
|
|
volumeMounts:
|
|
- name: paperless-ai-data
|
|
mountPath: /data
|
|
containers:
|
|
- name: paperless-ai
|
|
image: clusterzx/paperless-ai:latest
|
|
env:
|
|
# Paperless-ngx connection
|
|
- name: PAPERLESS_API_URL
|
|
value: "http://paperless.paperless.svc.cluster.local:8000"
|
|
- name: PAPERLESS_API_TOKEN
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: paperless-ai-config
|
|
key: PAPERLESS_API_TOKEN
|
|
- name: PAPERLESS_USERNAME
|
|
value: "admin"
|
|
# LLM API — via public gateway with JWT auth
|
|
- name: AI_PROVIDER
|
|
value: "custom"
|
|
- name: CUSTOM_BASE_URL
|
|
value: "https://api.riotpiao.com/v1"
|
|
# Token will be read from file at runtime by the application
|
|
# The init container fetches it and stores in /app/data/llm_token.txt
|
|
- name: CUSTOM_API_KEY_FILE
|
|
value: "/app/data/llm_token.txt"
|
|
- name: CUSTOM_MODEL
|
|
value: "qwen2.5:3b-instruct"
|
|
# Behavior - scan for new documents and tag them
|
|
- name: SCAN_INTERVAL
|
|
value: "60"
|
|
- name: PROCESS_PREDEFINED_DOCUMENTS
|
|
value: "no"
|
|
- name: ADD_AI_TAG
|
|
value: "yes"
|
|
- name: AI_TAG_NAME
|
|
value: "ai-processed"
|
|
- name: USE_PROMPT_TAGS
|
|
value: "yes"
|
|
- name: ADD_AI_DESCRIPTIONS
|
|
value: "yes"
|
|
volumeMounts:
|
|
- name: paperless-ai-data
|
|
mountPath: /app/data
|
|
resources:
|
|
requests:
|
|
cpu: 100m
|
|
memory: 512Mi
|
|
limits:
|
|
cpu: "1"
|
|
memory: 2Gi
|