gitarsenal-cli 1.2.6 โ†’ 1.2.8

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.6",
3
+ "version": "1.2.8",
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
@@ -18,15 +18,12 @@ The GitArsenal CLI integrates with Modal for creating sandboxes and SSH containe
18
18
  For enhanced security, GitArsenal CLI now automatically cleans up Modal tokens after SSH containers are created. This ensures that your Modal token is not left in the environment or on disk after the container is started.
19
19
 
20
20
  The cleanup process:
21
- 1. Removes real Modal token environment variables (MODAL_TOKEN_ID, MODAL_TOKEN, MODAL_TOKEN_SECRET)
22
- 2. Deletes real Modal token files (.modal/token.json, .modal/token_alt.json, .modalconfig)
23
- 3. Invalidates Modal sessions by removing session files and directories
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
- 6. Runs automatically after SSH container creation
27
- 7. Runs on service shutdown via signal handlers
28
-
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.
21
+ 1. Removes Modal token environment variables (MODAL_TOKEN_ID, MODAL_TOKEN, MODAL_TOKEN_SECRET)
22
+ 2. Deletes the ~/.modal.toml file which contains the authentication token
23
+ 3. Runs automatically after SSH container creation
24
+ 4. Runs on service shutdown via signal handlers
25
+
26
+ This simple but effective approach 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
27
 
31
28
  ## Usage
32
29
 
@@ -215,7 +215,7 @@ def cleanup_modal_token():
215
215
  logger.info("๐Ÿงน Cleaning up Modal token for security...")
216
216
 
217
217
  try:
218
- # Remove real token from environment variables
218
+ # Remove token from environment variables
219
219
  if "MODAL_TOKEN_ID" in os.environ:
220
220
  del os.environ["MODAL_TOKEN_ID"]
221
221
  logger.info("โœ… Removed MODAL_TOKEN_ID from environment")
@@ -228,127 +228,13 @@ def cleanup_modal_token():
228
228
  del os.environ["MODAL_TOKEN_SECRET"]
229
229
  logger.info("โœ… Removed MODAL_TOKEN_SECRET from environment")
230
230
 
231
- # Delete token files
231
+ # Delete ~/.modal.toml file
232
232
  from pathlib import Path
233
- modal_dir = Path.home() / ".modal"
234
- if modal_dir.exists():
235
- # Delete token.json
236
- token_file = modal_dir / "token.json"
237
- if token_file.exists():
238
- token_file.unlink()
239
- logger.info(f"โœ… Deleted token file at {token_file}")
240
-
241
- # Delete token_alt.json if it exists
242
- token_alt_file = modal_dir / "token_alt.json"
243
- if token_alt_file.exists():
244
- token_alt_file.unlink()
245
- logger.info(f"โœ… Deleted alternative token file at {token_alt_file}")
233
+ modal_toml = Path.home() / ".modal.toml"
234
+ if modal_toml.exists():
235
+ modal_toml.unlink()
236
+ logger.info(f"โœ… Deleted Modal token file at {modal_toml}")
246
237
 
247
- # Delete .modalconfig file
248
- modalconfig_file = Path.home() / ".modalconfig"
249
- if modalconfig_file.exists():
250
- modalconfig_file.unlink()
251
- logger.info(f"โœ… Deleted .modalconfig file at {modalconfig_file}")
252
-
253
- # Try to invalidate Modal sessions
254
- try:
255
- logger.info("๐Ÿ”‘ Invalidating Modal sessions...")
256
-
257
- # Try to directly modify Modal's session files
258
- try:
259
- # Check for session files in .modal directory
260
- session_dir = modal_dir / "sessions"
261
- if session_dir.exists():
262
- import shutil
263
- shutil.rmtree(session_dir)
264
- logger.info(f"โœ… Removed Modal sessions directory at {session_dir}")
265
-
266
- # Also check for any other potential session files
267
- for file in os.listdir(modal_dir) if modal_dir.exists() else []:
268
- if "session" in file.lower() or "auth" in file.lower():
269
- file_path = modal_dir / file
270
- if file_path.is_file():
271
- file_path.unlink()
272
- logger.info(f"โœ… Removed Modal session file: {file_path}")
273
- except Exception as e:
274
- logger.warning(f"โš ๏ธ Error removing Modal sessions: {e}")
275
-
276
- except Exception as e:
277
- logger.warning(f"โš ๏ธ Error during Modal session invalidation: {e}")
278
-
279
- # Create corrupted token files that will cause Modal CLI to fail
280
- try:
281
- logger.info("๐Ÿ”’ Creating corrupted Modal token files...")
282
-
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
-
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}")
293
-
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()
310
-
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}")
348
-
349
- except Exception as e:
350
- logger.warning(f"โš ๏ธ Error creating corrupted token files: {e}")
351
-
352
238
  logger.info("โœ… Modal token cleanup completed successfully")
353
239
  except Exception as e:
354
240
  logger.error(f"โŒ Error during Modal token cleanup: {e}")
@@ -3298,7 +3298,7 @@ def cleanup_modal_token():
3298
3298
  print("๐Ÿงน Cleaning up Modal token for security...")
3299
3299
 
3300
3300
  try:
3301
- # Remove real token from environment variables
3301
+ # Remove token from environment variables
3302
3302
  if "MODAL_TOKEN_ID" in os.environ:
3303
3303
  del os.environ["MODAL_TOKEN_ID"]
3304
3304
  print("โœ… Removed MODAL_TOKEN_ID from environment")
@@ -3311,130 +3311,13 @@ def cleanup_modal_token():
3311
3311
  del os.environ["MODAL_TOKEN_SECRET"]
3312
3312
  print("โœ… Removed MODAL_TOKEN_SECRET from environment")
3313
3313
 
3314
- # Delete token files
3314
+ # Delete ~/.modal.toml file
3315
3315
  home_dir = os.path.expanduser("~")
3316
- modal_dir = os.path.join(home_dir, ".modal")
3317
- if os.path.exists(modal_dir):
3318
- # Delete token.json
3319
- token_file = os.path.join(modal_dir, "token.json")
3320
- if os.path.exists(token_file):
3321
- os.remove(token_file)
3322
- print(f"โœ… Deleted token file at {token_file}")
3323
-
3324
- # Delete token_alt.json if it exists
3325
- token_alt_file = os.path.join(modal_dir, "token_alt.json")
3326
- if os.path.exists(token_alt_file):
3327
- os.remove(token_alt_file)
3328
- print(f"โœ… Deleted alternative token file at {token_alt_file}")
3329
-
3330
- # Delete .modalconfig file
3331
- modalconfig_file = os.path.join(home_dir, ".modalconfig")
3332
- if os.path.exists(modalconfig_file):
3333
- os.remove(modalconfig_file)
3334
- print(f"โœ… Deleted .modalconfig file at {modalconfig_file}")
3335
-
3336
- # Try to invalidate Modal sessions
3337
- try:
3338
- print("๐Ÿ”‘ Invalidating Modal sessions...")
3339
-
3340
- # Try to directly modify Modal's session files
3341
- try:
3342
- # Check for session files in .modal directory
3343
- session_dir = os.path.join(modal_dir, "sessions")
3344
- if os.path.exists(session_dir):
3345
- import shutil
3346
- shutil.rmtree(session_dir)
3347
- print(f"โœ… Removed Modal sessions directory at {session_dir}")
3348
-
3349
- # Also check for any other potential session files
3350
- for file in os.listdir(modal_dir) if os.path.exists(modal_dir) else []:
3351
- if "session" in file.lower() or "auth" in file.lower():
3352
- file_path = os.path.join(modal_dir, file)
3353
- if os.path.isfile(file_path):
3354
- os.remove(file_path)
3355
- print(f"โœ… Removed Modal session file: {file_path}")
3356
- except Exception as e:
3357
- print(f"โš ๏ธ Error removing Modal sessions: {e}")
3358
-
3359
- except Exception as e:
3360
- print(f"โš ๏ธ Error during Modal session invalidation: {e}")
3361
-
3362
- # Create corrupted token files that will cause Modal CLI to fail
3363
- try:
3364
- print("๐Ÿ”’ Creating corrupted Modal token files...")
3365
-
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}")
3434
-
3435
- except Exception as e:
3436
- print(f"โš ๏ธ Error creating corrupted token files: {e}")
3437
-
3316
+ modal_toml = os.path.join(home_dir, ".modal.toml")
3317
+ if os.path.exists(modal_toml):
3318
+ os.remove(modal_toml)
3319
+ print(f"โœ… Deleted Modal token file at {modal_toml}")
3320
+
3438
3321
  print("โœ… Modal token cleanup completed successfully")
3439
3322
  except Exception as e:
3440
3323
  print(f"โŒ Error during Modal token cleanup: {e}")