cdborinstein Claude Opus 4.5 commited on
Commit
1cbfdb8
·
1 Parent(s): e16f426

Security hardening: delete default users and use custom API key

Browse files

Replace base image startup with custom start.sh that deletes default
Argilla users (owner, admin, argilla) and sets ARGILLA_API_KEY on
the custom admin user. Fixes backup 401 and makes Space safe to go public.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Files changed (3) hide show
  1. Dockerfile +3 -1
  2. Procfile +1 -1
  3. start.sh +62 -9
Dockerfile CHANGED
@@ -3,8 +3,10 @@ FROM argilla/argilla-quickstart:latest
3
  # Install dependencies for backup script (uses REST API, no argilla client needed)
4
  RUN pip install --no-cache-dir huggingface_hub
5
 
6
- # Copy backup script to a location honcho can find
7
  COPY backup_to_hub.py /home/argilla/backup_to_hub.py
 
 
8
 
9
  # Copy custom Procfile that adds backup process
10
  COPY Procfile /home/argilla/Procfile
 
3
  # Install dependencies for backup script (uses REST API, no argilla client needed)
4
  RUN pip install --no-cache-dir huggingface_hub
5
 
6
+ # Copy backup script and custom startup
7
  COPY backup_to_hub.py /home/argilla/backup_to_hub.py
8
+ COPY start.sh /home/argilla/start.sh
9
+ RUN chmod +x /home/argilla/start.sh
10
 
11
  # Copy custom Procfile that adds backup process
12
  COPY Procfile /home/argilla/Procfile
Procfile CHANGED
@@ -1,3 +1,3 @@
1
  elastic: /usr/share/elasticsearch/bin/elasticsearch
2
- argilla: sleep 30; /bin/bash start_argilla_server.sh
3
  backup: sleep 60; python /home/argilla/backup_to_hub.py
 
1
  elastic: /usr/share/elasticsearch/bin/elasticsearch
2
+ argilla: sleep 30; /bin/bash /home/argilla/start.sh
3
  backup: sleep 60; python /home/argilla/backup_to_hub.py
start.sh CHANGED
@@ -1,24 +1,77 @@
1
  #!/bin/bash
2
 
3
- # Initialize database (run migrations)
4
  echo "Running database migrations..."
5
  python -m argilla_server database migrate
6
 
7
- # Create default user if USERNAME and PASSWORD are set
8
  if [ -n "$USERNAME" ] && [ -n "$PASSWORD" ]; then
9
- echo "Creating admin user..."
10
  python -m argilla_server database users create \
11
  --username "$USERNAME" \
12
  --password "$PASSWORD" \
13
  --role owner || echo "User may already exist, continuing..."
14
  fi
15
 
16
- # Start backup script in background (only if HF_TOKEN is set)
17
- if [ -n "$HF_TOKEN" ]; then
18
- python /app/backup_to_hub.py &
19
- else
20
- echo "WARNING: HF_TOKEN not set, backup disabled"
21
- fi
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
  # Start Argilla server
24
  exec python -m argilla_server start --host 0.0.0.0 --port 6900
 
1
  #!/bin/bash
2
 
3
+ # Initialize database (run migrations - this also creates default users)
4
  echo "Running database migrations..."
5
  python -m argilla_server database migrate
6
 
7
+ # Create custom admin user from env vars
8
  if [ -n "$USERNAME" ] && [ -n "$PASSWORD" ]; then
9
+ echo "Creating admin user: $USERNAME"
10
  python -m argilla_server database users create \
11
  --username "$USERNAME" \
12
  --password "$PASSWORD" \
13
  --role owner || echo "User may already exist, continuing..."
14
  fi
15
 
16
+ # Security hardening: delete default users and set custom API key
17
+ echo "Securing default user accounts..."
18
+ python3 << 'PYEOF'
19
+ import sqlite3
20
+ import os
21
+ import glob
22
+
23
+ # Find the Argilla SQLite database
24
+ search_paths = [
25
+ os.path.expanduser("~/.argilla/argilla.db"),
26
+ "/home/argilla/.argilla/argilla.db",
27
+ ]
28
+ # Also search recursively
29
+ search_paths += glob.glob("/home/argilla/.argilla/**/*.db", recursive=True)
30
+ search_paths += glob.glob("/home/argilla/**/*.db", recursive=True)
31
+
32
+ db_path = None
33
+ for candidate in search_paths:
34
+ if os.path.exists(candidate):
35
+ db_path = candidate
36
+ break
37
+
38
+ if not db_path:
39
+ print("WARNING: Could not find Argilla database, skipping security hardening")
40
+ else:
41
+ print(f"Found database at: {db_path}")
42
+ conn = sqlite3.connect(db_path)
43
+ cursor = conn.cursor()
44
+
45
+ # Show current users
46
+ cursor.execute("SELECT username, role FROM users")
47
+ print(f"Users before hardening: {cursor.fetchall()}")
48
+
49
+ username = os.environ.get("USERNAME", "")
50
+ api_key = os.environ.get("ARGILLA_API_KEY", "")
51
+
52
+ # Delete default users (owner, admin, argilla) but keep our custom user
53
+ default_users = ["owner", "admin", "argilla"]
54
+ for default_user in default_users:
55
+ if default_user != username:
56
+ cursor.execute("DELETE FROM users WHERE username = ?", (default_user,))
57
+ if cursor.rowcount > 0:
58
+ print(f"Deleted default user: {default_user}")
59
+
60
+ # Set custom API key on our admin user so backup script can authenticate
61
+ if api_key and username:
62
+ cursor.execute("UPDATE users SET api_key = ? WHERE username = ?", (api_key, username))
63
+ if cursor.rowcount > 0:
64
+ print(f"Updated API key for user: {username}")
65
+
66
+ conn.commit()
67
+
68
+ # Verify
69
+ cursor.execute("SELECT username, role FROM users")
70
+ print(f"Users after hardening: {cursor.fetchall()}")
71
+ conn.close()
72
+ PYEOF
73
+
74
+ echo "Security hardening complete."
75
 
76
  # Start Argilla server
77
  exec python -m argilla_server start --host 0.0.0.0 --port 6900