Files

38 lines
1.3 KiB
Python

"""Generate a human key once; deployment configuration contains only its digest.
Run locally in a private terminal. Do not redirect the complete output into deployment config.
"""
import argparse
import hashlib
import json
import re
import secrets
import uuid
from datetime import UTC, datetime, timedelta
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--subject", required=True)
parser.add_argument("--role", choices=("viewer", "operator", "admin"), required=True)
parser.add_argument("--days", type=int, default=30)
args = parser.parse_args()
if not re.fullmatch(r"[a-zA-Z0-9][a-zA-Z0-9._@-]{0,127}", args.subject):
parser.error("subject must be 1-128 letters, digits, dots, underscores, @ or hyphens")
if args.subject == "legacy-operator" or not 1 <= args.days <= 365:
parser.error("reserved subject or expiry outside 1-365 days")
token = "mfop_" + secrets.token_urlsafe(32)
record = {
"credential_id": str(uuid.uuid4()),
"subject": args.subject,
"role": args.role,
"token_sha256": hashlib.sha256(token.encode()).hexdigest(),
"expires_at": (datetime.now(UTC) + timedelta(days=args.days)).isoformat(),
}
print(json.dumps({"one_time_key": token, "deployment_record": record}, indent=2))
if __name__ == "__main__":
main()