gitarsenal-cli 1.2.5 โ†’ 1.2.7

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.7",
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. 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
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, while still allowing users to run basic Modal CLI commands. Any operations requiring authentication will fail, effectively logging the user out from Modal.
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,114 +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
- # Set invalid Modal tokens using the Modal CLI
280
- try:
281
- logger.info("๐Ÿ”„ Setting invalid Modal tokens...")
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"
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
- )
297
-
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}")
330
-
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")
335
-
336
- except Exception as e:
337
- logger.warning(f"โš ๏ธ Error setting invalid Modal tokens: {e}")
338
-
339
238
  logger.info("โœ… Modal token cleanup completed successfully")
340
239
  except Exception as e:
341
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,116 +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
- # Set invalid Modal tokens using the Modal CLI
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
- )
3381
-
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")
3420
-
3421
- except Exception as e:
3422
- print(f"โš ๏ธ Error setting invalid Modal tokens: {e}")
3423
-
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
+
3424
3321
  print("โœ… Modal token cleanup completed successfully")
3425
3322
  except Exception as e:
3426
3323
  print(f"โŒ Error during Modal token cleanup: {e}")