Files
A-Team-Security-Infra-Agent…/deploy/scripts/ocir-login.py

132 lines
4.6 KiB
Python
Executable File

#!/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 <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()