gitarsenal-cli 1.2.5 → 1.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitarsenal-cli",
3
- "version": "1.2.5",
3
+ "version": "1.2.6",
4
4
  "description": "CLI tool for creating Modal sandboxes with GitHub repositories",
5
5
  "main": "index.js",
6
6
  "bin": {
package/python/README.md CHANGED
@@ -21,12 +21,12 @@ The cleanup process:
21
21
  1. Removes real Modal token environment variables (MODAL_TOKEN_ID, MODAL_TOKEN, MODAL_TOKEN_SECRET)
22
22
  2. Deletes real Modal token files (.modal/token.json, .modal/token_alt.json, .modalconfig)
23
23
  3. Invalidates Modal sessions by removing session files and directories
24
- 4. Sets invalid Modal tokens using the `modal token set` command with a dedicated profile
25
- 5. Falls back to manually setting placeholder tokens if the command fails
24
+ 4. Creates corrupted token files that will cause Modal CLI authentication to fail
25
+ 5. Creates a wrapper script around the Modal CLI that specifically blocks the `modal shell` command
26
26
  6. Runs automatically after SSH container creation
27
27
  7. Runs on service shutdown via signal handlers
28
28
 
29
- This prevents potential token leakage when containers are shared or when the service is stopped, while still allowing users to run basic Modal CLI commands. Any operations requiring authentication will fail, effectively logging the user out from Modal.
29
+ This prevents potential token leakage when containers are shared or when the service is stopped, and ensures that users cannot continue to use Modal CLI commands like `modal shell` after the container is created.
30
30
 
31
31
  ## Usage
32
32
 
@@ -276,65 +276,78 @@ def cleanup_modal_token():
276
276
  except Exception as e:
277
277
  logger.warning(f"⚠️ Error during Modal session invalidation: {e}")
278
278
 
279
- # Set invalid Modal tokens using the Modal CLI
279
+ # Create corrupted token files that will cause Modal CLI to fail
280
280
  try:
281
- logger.info("🔄 Setting invalid Modal tokens...")
281
+ logger.info("🔒 Creating corrupted Modal token files...")
282
282
 
283
- # Use modal token set command with invalid credentials
284
- invalid_token_id = "ak-invalid-token-not-valid"
285
- invalid_token_secret = "as-invalid-secret-not-valid"
286
- profile = "gitarsenal"
283
+ # Create .modal directory if it doesn't exist
284
+ if not modal_dir.exists():
285
+ modal_dir.mkdir(parents=True)
286
+ logger.info(f"✅ Created Modal directory at {modal_dir}")
287
287
 
288
- # Run the modal token set command
289
- result = subprocess.run(
290
- ["modal", "token", "set",
291
- "--token-id", invalid_token_id,
292
- "--token-secret", invalid_token_secret,
293
- f"--profile={profile}"],
294
- capture_output=True,
295
- text=True
296
- )
288
+ # Create a corrupted token.json file
289
+ token_file = modal_dir / "token.json"
290
+ with open(token_file, 'w') as f:
291
+ f.write('{"corrupted": true, "message": "Token has been invalidated for security reasons"}')
292
+ logger.info(f"✅ Created corrupted token file at {token_file}")
297
293
 
298
- if result.returncode == 0:
299
- logger.info(f"✅ Successfully set invalid Modal tokens with profile '{profile}'")
300
- else:
301
- logger.warning(f"⚠️ Error setting invalid Modal tokens: {result.stderr}")
302
-
303
- # Fall back to manually setting placeholder tokens
304
- logger.info("🔄 Falling back to manually setting placeholder tokens...")
305
-
306
- # Create .modal directory if it doesn't exist
307
- if not modal_dir.exists():
308
- modal_dir.mkdir(parents=True)
309
- logger.info(f" Created Modal directory at {modal_dir}")
310
-
311
- # Set placeholder tokens in token.json
312
- placeholder_token_id = "ak-placeholder-token-not-valid"
313
- placeholder_token_secret = "as-placeholder-secret-not-valid"
314
-
315
- # Create token.json with placeholder values
316
- token_file = modal_dir / "token.json"
317
- with open(token_file, 'w') as f:
318
- import json
319
- json.dump({
320
- "token_id": placeholder_token_id,
321
- "token_secret": placeholder_token_secret
322
- }, f)
323
- logger.info(f"✅ Created placeholder token file at {token_file}")
324
-
325
- # Create .modalconfig file with placeholder values
326
- with open(modalconfig_file, 'w') as f:
327
- f.write(f"token_id = {placeholder_token_id}\n")
328
- f.write(f"token_secret = {placeholder_token_secret}\n")
329
- logger.info(f"✅ Created placeholder .modalconfig file at {modalconfig_file}")
294
+ # Create a corrupted .modalconfig file
295
+ modalconfig_file = Path.home() / ".modalconfig"
296
+ with open(modalconfig_file, 'w') as f:
297
+ f.write("# This file has been corrupted for security reasons\n")
298
+ f.write("corrupted = true\n")
299
+ logger.info(f"✅ Created corrupted .modalconfig file at {modalconfig_file}")
300
+
301
+ # Try to disable the modal shell command specifically
302
+ try:
303
+ # Find the modal executable path
304
+ result = subprocess.run(
305
+ ["which", "modal"],
306
+ capture_output=True,
307
+ text=True
308
+ )
309
+ modal_path = result.stdout.strip()
330
310
 
331
- # Set placeholder values in environment variables
332
- os.environ["MODAL_TOKEN_ID"] = placeholder_token_id
333
- os.environ["MODAL_TOKEN_SECRET"] = placeholder_token_secret
334
- logger.info("✅ Set placeholder tokens in environment variables")
311
+ if modal_path:
312
+ logger.info(f"📍 Found Modal CLI at: {modal_path}")
313
+
314
+ # Create a wrapper script that intercepts the shell command
315
+ modal_shell_wrapper = """#!/bin/bash
316
+ if [[ "$1" == "shell" ]]; then
317
+ echo "❌ Modal shell has been disabled for security reasons."
318
+ echo "Modal token has been removed after SSH container creation."
319
+ exit 1
320
+ fi
321
+
322
+ # Pass all other commands to the real modal CLI
323
+ REAL_MODAL=$(which modal.real 2>/dev/null)
324
+ if [ -n "$REAL_MODAL" ]; then
325
+ exec "$REAL_MODAL" "$@"
326
+ else
327
+ echo "❌ Modal CLI has been disabled for security reasons."
328
+ echo "Modal token has been removed after SSH container creation."
329
+ exit 1
330
+ fi
331
+ """
332
+
333
+ # Rename the original modal executable
334
+ os.rename(modal_path, f"{modal_path}.real")
335
+ logger.info(f"✅ Renamed original Modal CLI to {modal_path}.real")
336
+
337
+ # Create a new modal script
338
+ with open(modal_path, 'w') as f:
339
+ f.write(modal_shell_wrapper)
340
+
341
+ # Make it executable
342
+ os.chmod(modal_path, 0o755)
343
+ logger.info(f"✅ Created Modal CLI wrapper at {modal_path}")
344
+ else:
345
+ logger.warning("⚠️ Could not find Modal CLI path")
346
+ except Exception as e:
347
+ logger.warning(f"⚠️ Error creating Modal CLI wrapper: {e}")
335
348
 
336
349
  except Exception as e:
337
- logger.warning(f"⚠️ Error setting invalid Modal tokens: {e}")
350
+ logger.warning(f"⚠️ Error creating corrupted token files: {e}")
338
351
 
339
352
  logger.info("✅ Modal token cleanup completed successfully")
340
353
  except Exception as e:
@@ -3359,67 +3359,81 @@ def cleanup_modal_token():
3359
3359
  except Exception as e:
3360
3360
  print(f"⚠️ Error during Modal session invalidation: {e}")
3361
3361
 
3362
- # Set invalid Modal tokens using the Modal CLI
3362
+ # Create corrupted token files that will cause Modal CLI to fail
3363
3363
  try:
3364
- print("🔄 Setting invalid Modal tokens...")
3365
- import subprocess
3366
-
3367
- # Use modal token set command with invalid credentials
3368
- invalid_token_id = "ak-invalid-token-not-valid"
3369
- invalid_token_secret = "as-invalid-secret-not-valid"
3370
- profile = "gitarsenal"
3371
-
3372
- # Run the modal token set command
3373
- result = subprocess.run(
3374
- ["modal", "token", "set",
3375
- "--token-id", invalid_token_id,
3376
- "--token-secret", invalid_token_secret,
3377
- f"--profile={profile}"],
3378
- capture_output=True,
3379
- text=True
3380
- )
3364
+ print("🔒 Creating corrupted Modal token files...")
3381
3365
 
3382
- if result.returncode == 0:
3383
- print(f"✅ Successfully set invalid Modal tokens with profile '{profile}'")
3384
- else:
3385
- print(f"⚠️ Error setting invalid Modal tokens: {result.stderr}")
3386
-
3387
- # Fall back to manually setting placeholder tokens
3388
- print("🔄 Falling back to manually setting placeholder tokens...")
3389
-
3390
- # Create .modal directory if it doesn't exist
3391
- if not os.path.exists(modal_dir):
3392
- os.makedirs(modal_dir)
3393
- print(f"✅ Created Modal directory at {modal_dir}")
3394
-
3395
- # Set placeholder tokens in token.json
3396
- placeholder_token_id = "ak-placeholder-token-not-valid"
3397
- placeholder_token_secret = "as-placeholder-secret-not-valid"
3398
-
3399
- # Create token.json with placeholder values
3400
- token_file = os.path.join(modal_dir, "token.json")
3401
- with open(token_file, 'w') as f:
3402
- import json
3403
- json.dump({
3404
- "token_id": placeholder_token_id,
3405
- "token_secret": placeholder_token_secret
3406
- }, f)
3407
- print(f" Created placeholder token file at {token_file}")
3408
-
3409
- # Create .modalconfig file with placeholder values
3410
- modalconfig_file = os.path.join(home_dir, ".modalconfig")
3411
- with open(modalconfig_file, 'w') as f:
3412
- f.write(f"token_id = {placeholder_token_id}\n")
3413
- f.write(f"token_secret = {placeholder_token_secret}\n")
3414
- print(f" Created placeholder .modalconfig file at {modalconfig_file}")
3415
-
3416
- # Set placeholder values in environment variables
3417
- os.environ["MODAL_TOKEN_ID"] = placeholder_token_id
3418
- os.environ["MODAL_TOKEN_SECRET"] = placeholder_token_secret
3419
- print(" Set placeholder tokens in environment variables")
3366
+ # Create .modal directory if it doesn't exist
3367
+ if not os.path.exists(modal_dir):
3368
+ os.makedirs(modal_dir)
3369
+ print(f" Created Modal directory at {modal_dir}")
3370
+
3371
+ # Create a corrupted token.json file
3372
+ token_file = os.path.join(modal_dir, "token.json")
3373
+ with open(token_file, 'w') as f:
3374
+ f.write('{"corrupted": true, "message": "Token has been invalidated for security reasons"}')
3375
+ print(f"✅ Created corrupted token file at {token_file}")
3376
+
3377
+ # Create a corrupted .modalconfig file
3378
+ modalconfig_file = os.path.join(home_dir, ".modalconfig")
3379
+ with open(modalconfig_file, 'w') as f:
3380
+ f.write("# This file has been corrupted for security reasons\n")
3381
+ f.write("corrupted = true\n")
3382
+ print(f"✅ Created corrupted .modalconfig file at {modalconfig_file}")
3383
+
3384
+ # Try to disable the modal shell command specifically
3385
+ try:
3386
+ import subprocess
3387
+ import sys
3388
+
3389
+ # Find the modal executable path
3390
+ result = subprocess.run(
3391
+ ["which", "modal"],
3392
+ capture_output=True,
3393
+ text=True
3394
+ )
3395
+ modal_path = result.stdout.strip()
3396
+
3397
+ if modal_path:
3398
+ print(f"📍 Found Modal CLI at: {modal_path}")
3399
+
3400
+ # Create a wrapper script that intercepts the shell command
3401
+ modal_shell_wrapper = """#!/bin/bash
3402
+ if [[ "$1" == "shell" ]]; then
3403
+ echo " Modal shell has been disabled for security reasons."
3404
+ echo "Modal token has been removed after SSH container creation."
3405
+ exit 1
3406
+ fi
3407
+
3408
+ # Pass all other commands to the real modal CLI
3409
+ REAL_MODAL=$(which modal.real 2>/dev/null)
3410
+ if [ -n "$REAL_MODAL" ]; then
3411
+ exec "$REAL_MODAL" "$@"
3412
+ else
3413
+ echo "❌ Modal CLI has been disabled for security reasons."
3414
+ echo "Modal token has been removed after SSH container creation."
3415
+ exit 1
3416
+ fi
3417
+ """
3418
+
3419
+ # Rename the original modal executable
3420
+ os.rename(modal_path, f"{modal_path}.real")
3421
+ print(f"✅ Renamed original Modal CLI to {modal_path}.real")
3422
+
3423
+ # Create a new modal script
3424
+ with open(modal_path, 'w') as f:
3425
+ f.write(modal_shell_wrapper)
3426
+
3427
+ # Make it executable
3428
+ os.chmod(modal_path, 0o755)
3429
+ print(f"✅ Created Modal CLI wrapper at {modal_path}")
3430
+ else:
3431
+ print("⚠️ Could not find Modal CLI path")
3432
+ except Exception as e:
3433
+ print(f"⚠️ Error creating Modal CLI wrapper: {e}")
3420
3434
 
3421
3435
  except Exception as e:
3422
- print(f"⚠️ Error setting invalid Modal tokens: {e}")
3436
+ print(f"⚠️ Error creating corrupted token files: {e}")
3423
3437
 
3424
3438
  print("✅ Modal token cleanup completed successfully")
3425
3439
  except Exception as e: