#!/usr/bin/env python3 """ OCIR Login Helper — Decrypts embedded credentials and performs docker login. The auth token is encrypted with Fernet (AES-128-CBC + HMAC-SHA256). A passphrase is required to decrypt — distribute it out-of-band (Slack, email). Usage: python ocir-login.py python ocir-login.py --passphrase python ocir-login.py --generate # Admin: encrypt a new token """ import argparse import base64 import getpass import hashlib import os import subprocess import sys # ── OCIR Configuration ───────────────────────────────────────────────────── OCIR_REGION = "us-ashburn-1" OCIR_ENDPOINT = f"{OCIR_REGION}.ocir.io" OCIR_NAMESPACE = "idi1o0a010nx" OCIR_USERNAME = f"{OCIR_NAMESPACE}/oracleidentitycloudservice/gustavo.nogueira@oracle.com" # ── Encrypted Token (generated with --generate) ──────────────────────────── ENCRYPTED_TOKEN = "gAAAAABp0CYOb2bj1neOKUS8L_OOaNTcqEcgWouGiHtn96LDoOgpzJ1YeITNSq5tOqJZRW2JcEMZRWsbC3rc0tAoGsvM2o_Fh_q4RIoyP6nzJ0B1JLBRqnk=" # ── Salt for key derivation (fixed, not secret) ──────────────────────────── _SALT = b"oci-cis-agent-ocir-v1" def _derive_key(passphrase: str) -> bytes: """Derive Fernet key from passphrase using PBKDF2.""" from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC from cryptography.hazmat.primitives import hashes kdf = PBKDF2HMAC( algorithm=hashes.SHA256(), length=32, salt=_SALT, iterations=600_000, ) return base64.urlsafe_b64encode(kdf.derive(passphrase.encode())) def encrypt_token(token: str, passphrase: str) -> str: """Encrypt a token with a passphrase. Returns base64 string.""" from cryptography.fernet import Fernet key = _derive_key(passphrase) f = Fernet(key) return f.encrypt(token.encode()).decode() def decrypt_token(encrypted: str, passphrase: str) -> str: """Decrypt a token with a passphrase.""" from cryptography.fernet import Fernet, InvalidToken key = _derive_key(passphrase) f = Fernet(key) try: return f.decrypt(encrypted.encode()).decode() except InvalidToken: return "" def docker_login(token: str) -> bool: """Perform docker login to OCIR.""" result = subprocess.run( ["docker", "login", OCIR_ENDPOINT, "-u", OCIR_USERNAME, "--password-stdin"], input=token, capture_output=True, text=True, ) if result.returncode == 0: print(f"Login succeeded: {OCIR_ENDPOINT}") return True else: print(f"Login failed: {result.stderr.strip()}") return False def main(): parser = argparse.ArgumentParser(description="OCIR Login Helper") parser.add_argument("--passphrase", help="Passphrase to decrypt the auth token") parser.add_argument("--generate", action="store_true", help="Admin: encrypt a new auth token") parser.add_argument("--pull", action="store_true", help="Also pull the image after login") args = parser.parse_args() if args.generate: print("=== Generate Encrypted Token ===") token = getpass.getpass("Auth Token (from OCI Console): ") passphrase = getpass.getpass("Passphrase (share with team): ") passphrase2 = getpass.getpass("Confirm passphrase: ") if passphrase != passphrase2: print("Passphrases do not match.") sys.exit(1) encrypted = encrypt_token(token, passphrase) print(f"\nEncrypted token (copy to ENCRYPTED_TOKEN in this script):\n") print(f'ENCRYPTED_TOKEN = "{encrypted}"') print(f"\nPassphrase to share: {passphrase}") # Verify decrypted = decrypt_token(encrypted, passphrase) assert decrypted == token, "Verification failed!" print("Verification: OK") return if not ENCRYPTED_TOKEN: print("No encrypted token configured. Run with --generate first.") sys.exit(1) passphrase = args.passphrase or getpass.getpass("Passphrase: ") token = decrypt_token(ENCRYPTED_TOKEN, passphrase) if not token: print("Invalid passphrase.") sys.exit(1) success = docker_login(token) if success and args.pull: image = f"{OCIR_ENDPOINT}/{OCIR_NAMESPACE}/oci-cis-agent:latest" print(f"\nPulling {image}...") subprocess.run(["docker", "pull", image]) # Clear sensitive data token = None passphrase = None if __name__ == "__main__": main()