"""Single-entry dev and dev-corp IOP token issuance workflow. Sensitive request data is accepted only as JSON on stdin. The command emits a redacted result and copies the raw token to the local macOS clipboard only after Edge activation, environment-specific API smoke, metadata synchronization, and leak checks pass. """ from __future__ import annotations import argparse import base64 import fcntl import hashlib import html import json import os import re import secrets import shlex import stat import subprocess import sys import time import unicodedata import urllib.error import urllib.parse import urllib.request from contextlib import contextmanager from html.parser import HTMLParser from pathlib import Path from typing import Any, NoReturn, cast ATLASSIAN_BASE_URL = "https://lgucorp.atlassian.net" CONFLUENCE_FOLDER_ID = "650886407" CONFLUENCE_TITLE = "IOP 계정 발급 현황" MANAGED_HEADING = "IOP 사용자 토큰 발급 현황" TABLE_HEADERS = ("사용자", "principal alias", "token ref", "상태", "동기화 시각") SUPPORTED_ENVIRONMENTS = ("dev", "dev-corp") class WorkflowFailure(RuntimeError): def __init__(self, code: str): self.code = code super().__init__(code) class ConfluenceHTTPFailure(WorkflowFailure): def __init__(self, status_code: int): self.status_code = status_code super().__init__(f"confluence_http_{status_code}") class CurlTransportFailure(WorkflowFailure): def __init__(self): super().__init__("curl_transport_failed") def fail(code: str) -> NoReturn: raise WorkflowFailure(code) def repo_root() -> Path: root = Path(__file__).resolve().parents[5] if not (root / ".git").exists(): fail("repo_root_invalid") return root def load_profile(root: Path, environment: str) -> dict[str, Any]: if environment not in SUPPORTED_ENVIRONMENTS: fail("environment_not_supported") path = ( root / "agent-ops/skills/project/openai-usage-token-issue/profiles" / f"{environment}.json" ) try: value = json.loads(path.read_text(encoding="utf-8")) except (OSError, json.JSONDecodeError): fail("environment_profile_invalid") if not isinstance(value, dict) or value.get("environment") != environment: fail("environment_profile_invalid") required_strings = ( "edge_ssh", "secret_store", "openai_smoke_transport", "openai_base_url", "smoke_model", "metrics_transport", "metrics_url", ) if any(not isinstance(value.get(key), str) or not value[key] for key in required_strings): fail("environment_profile_invalid") if not isinstance(value.get("confluence_enabled"), bool): fail("environment_profile_invalid") expected_stores = { "dev": "token/.dev-iop-token", "dev-corp": "token/.dev-corp-iop-token", } expected_ssh = {"dev": "toki@toki-labs.com", "dev-corp": "toki@iop.ai.kr"} if value["secret_store"] != expected_stores[environment]: fail("environment_profile_invalid") if value["edge_ssh"] != expected_ssh[environment]: fail("environment_profile_invalid") parsed_api = urllib.parse.urlsplit(str(value["openai_base_url"])) transport = value["openai_smoke_transport"] if transport == "public-https": if parsed_api.scheme != "https" or not parsed_api.netloc: fail("environment_profile_invalid") elif transport == "ssh-loopback": if parsed_api.scheme != "http" or parsed_api.hostname not in {"127.0.0.1", "::1", "localhost"}: fail("environment_profile_invalid") else: fail("environment_profile_invalid") if value["metrics_transport"] not in {"public-http", "ssh-loopback"}: fail("environment_profile_invalid") if value["confluence_enabled"] and not isinstance( value.get("confluence_user_store"), str ): fail("environment_profile_invalid") return cast(dict[str, Any], value) def run_quiet( argv: list[str], *, cwd: Path, input_bytes: bytes | None = None, timeout: int = 30 ) -> subprocess.CompletedProcess[bytes]: try: return subprocess.run( argv, cwd=cwd, input=input_bytes, capture_output=True, timeout=timeout, check=False, ) except subprocess.TimeoutExpired: fail("command_timeout") def git_is_ignored(root: Path, path: Path) -> bool: relative = path.relative_to(root) result = run_quiet(["git", "check-ignore", "-q", "--", str(relative)], cwd=root) return result.returncode == 0 def git_is_tracked(root: Path, path: Path) -> bool: relative = path.relative_to(root) result = run_quiet( ["git", "ls-files", "--error-unmatch", "--", str(relative)], cwd=root ) return result.returncode == 0 def require_secure_secret(root: Path, path: Path, *, must_exist: bool = True) -> None: if path.is_symlink() or path.parent.is_symlink(): fail("secret_store_symlink_invalid") try: path.parent.resolve().relative_to(root.resolve()) except ValueError: fail("secret_store_path_invalid") if must_exist and not path.is_file(): fail("secret_store_missing") if path.exists(): mode = stat.S_IMODE(path.stat().st_mode) if mode != 0o600: fail("secret_store_mode_invalid") if not git_is_ignored(root, path) or git_is_tracked(root, path): fail("secret_store_tracking_invalid") @contextmanager def local_transaction_lock(root: Path, *, shared: bool): token_dir = root / "token" if ( not token_dir.is_dir() or token_dir.is_symlink() or not git_is_ignored(root, token_dir) ): fail("local_transaction_lock_invalid") flags = os.O_RDONLY | getattr(os, "O_DIRECTORY", 0) | getattr(os, "O_NOFOLLOW", 0) try: descriptor = os.open(token_dir, flags) except OSError: fail("local_transaction_lock_invalid") try: operation = fcntl.LOCK_SH if shared else fcntl.LOCK_EX try: fcntl.flock(descriptor, operation | fcntl.LOCK_NB) except BlockingIOError: fail("local_transaction_busy") yield finally: try: fcntl.flock(descriptor, fcntl.LOCK_UN) finally: os.close(descriptor) def normalize_alias(principal_ref: str, requested: str | None) -> str: source = requested.strip() if requested else principal_ref.split("@", 1)[0] ascii_value = ( unicodedata.normalize("NFKD", source).encode("ascii", "ignore").decode("ascii") ) alias = re.sub(r"[^a-z0-9]+", "-", ascii_value.lower()).strip("-") alias = re.sub(r"-+", "-", alias)[:40].rstrip("-") if not re.fullmatch(r"[a-z0-9][a-z0-9-]{0,39}", alias): fail("principal_alias_invalid") return alias def parse_request(stdin_text: str) -> dict[str, str]: try: payload = json.loads(stdin_text) except json.JSONDecodeError: fail("request_json_invalid") if not isinstance(payload, dict): fail("request_json_invalid") if payload.get("operation", "create") != "create": fail("operation_not_supported_by_single_entry") environment = payload.get("env") if not isinstance(environment, str) or environment not in SUPPORTED_ENVIRONMENTS: fail("environment_not_supported") principal_value = payload.get("principal_ref") alias_value = payload.get("principal_alias") token_ref_value = payload.get("token_ref") if not isinstance(principal_value, str): fail("principal_ref_invalid") if alias_value is not None and not isinstance(alias_value, str): fail("principal_alias_invalid") if token_ref_value is not None and not isinstance(token_ref_value, str): fail("token_ref_invalid") principal_ref = principal_value.strip() if ( not principal_ref or len(principal_ref) > 254 or any(char in principal_ref for char in "\r\n:\0") or any(char.isspace() for char in principal_ref) ): fail("principal_ref_invalid") alias = normalize_alias(principal_ref, alias_value) token_ref = (token_ref_value or f"iop-{environment}-{alias}").strip() if not re.fullmatch(r"[a-z0-9][a-z0-9._:-]{2,79}", token_ref): fail("token_ref_invalid") return { "operation": "create", "env": environment, "principal_ref": principal_ref, "principal_alias": alias, "token_ref": token_ref, } def read_store(path: Path) -> tuple[bytes, dict[str, str]]: if not path.exists(): return b"", {} raw_bytes = path.read_bytes() try: text = raw_bytes.decode("utf-8") except UnicodeDecodeError: fail("secret_store_encoding_invalid") entries: dict[str, str] = {} for line in text.splitlines(): if not line.strip(): continue key, separator, token = line.partition(": ") if ( not separator or not key or key.strip() != key or not token.startswith("iop_") or token.strip() != token or key in entries or "\n" in token or "\r" in token ): fail("secret_store_format_invalid") entries[key] = token return raw_bytes, entries def write_candidate(path: Path, content: bytes) -> Path: path.parent.mkdir(mode=0o700, parents=True, exist_ok=True) os.chmod(path.parent, 0o700) candidate = ( path.parent / f".{path.name}.candidate-{os.getpid()}-{secrets.token_hex(4)}" ) descriptor = os.open(candidate, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600) try: with os.fdopen(descriptor, "wb") as stream: stream.write(content) stream.flush() os.fsync(stream.fileno()) except BaseException: candidate.unlink(missing_ok=True) raise return candidate def atomic_restore(path: Path, content: bytes | None) -> None: if content is None: path.unlink(missing_ok=True) return candidate = write_candidate(path, content) os.replace(candidate, path) os.chmod(path, 0o600) def sha256_text(value: str) -> str: return hashlib.sha256(value.encode("utf-8")).hexdigest() def curl_config_quote(value: str) -> str: return ( value.replace("\\", "\\\\") .replace('"', '\\"') .replace("\r", "") .replace("\n", "") ) def curl_request( root: Path, method: str, url: str, headers: list[str], payload: dict[str, Any] | None, *, timeout: int, ) -> tuple[int, bytes]: marker = b"\n__IOP_HTTP_STATUS__" config_lines = [ "silent", "show-error", 'proto = "=https"', f"max-time = {timeout}", f'request = "{curl_config_quote(method)}"', f'url = "{curl_config_quote(url)}"', 'write-out = "\\n__IOP_HTTP_STATUS__%{http_code}"', ] config_lines.extend(f'header = "{curl_config_quote(header)}"' for header in headers) argv = ["curl", "-q", "--config", "-"] payload_path: Path | None = None if payload is not None: payload_bytes = json.dumps( payload, ensure_ascii=False, separators=(",", ":") ).encode("utf-8") payload_path = write_candidate(root / "token/.curl-json-payload", payload_bytes) argv.extend(["--data-binary", f"@{payload_path}"]) try: result = run_quiet( argv, cwd=root, input_bytes=("\n".join(config_lines) + "\n").encode("utf-8"), timeout=timeout + 5, ) finally: if payload_path: payload_path.unlink(missing_ok=True) if result.returncode != 0: raise CurlTransportFailure() body, separator, status_bytes = result.stdout.rpartition(marker) if not separator or not status_bytes.isdigit(): raise CurlTransportFailure() return int(status_bytes), body def remote_call( root: Path, profile: dict[str, Any], payload: dict[str, Any], *, timeout: int, ) -> dict[str, Any]: helper = ( root / "agent-ops/skills/project/openai-usage-token-issue/scripts/remote_edge_transaction.rb" ) source = helper.read_text(encoding="utf-8") remote_command = "ruby -e " + shlex.quote(source) remote_payload = dict(payload) remote_payload["environment"] = profile["environment"] result = run_quiet( [ "ssh", "-o", "BatchMode=yes", "-o", "ConnectTimeout=8", str(profile["edge_ssh"]), remote_command, ], cwd=root, input_bytes=json.dumps(remote_payload, separators=(",", ":")).encode("utf-8"), timeout=timeout, ) parsed: dict[str, Any] | None = None for line in reversed(result.stdout.decode("utf-8", "replace").splitlines()): try: value = json.loads(line) except json.JSONDecodeError: continue if isinstance(value, dict) and "status" in value: parsed = value break if parsed is None: fail("edge_remote_response_invalid") if result.returncode != 0 or parsed.get("status") == "blocked": code = str(parsed.get("code", "edge_remote_failed")) if not re.fullmatch(r"[a-z0-9_]+", code): code = "edge_remote_failed" fail(code if code.startswith("edge_") else f"edge_{code}") return parsed class ConfluenceClient: def __init__(self, root: Path, username: str, token: str): self.root = root self.username = username self.token = token def request( self, method: str, path_or_url: str, payload: dict[str, Any] | None = None ) -> dict[str, Any]: url = ( path_or_url if path_or_url.startswith("https://") else ATLASSIAN_BASE_URL + path_or_url ) parsed_url = urllib.parse.urlsplit(url) if ( parsed_url.scheme != "https" or parsed_url.netloc != "lgucorp.atlassian.net" or not parsed_url.path.startswith("/wiki/") ): fail("confluence_url_invalid") try: status_code, data = curl_request( self.root, method, url, [ f"Authorization: Basic {base64_basic(self.username, self.token)}", "Accept: application/json", "Content-Type: application/json", ], payload, timeout=20, ) except CurlTransportFailure: fail("confluence_network_failed") if status_code < 200 or status_code >= 300: raise ConfluenceHTTPFailure(status_code) try: parsed = json.loads(data) except json.JSONDecodeError: fail("confluence_response_invalid") if not isinstance(parsed, dict): fail("confluence_response_invalid") return parsed def base64_basic(username: str, token: str) -> str: return base64.b64encode(f"{username}:{token}".encode()).decode("ascii") def confluence_storage(page: dict[str, Any]) -> str: body = page.get("body") if not isinstance(body, dict): fail("confluence_body_missing") storage = body.get("storage") if not isinstance(storage, dict) or not isinstance(storage.get("value"), str): fail("confluence_body_missing") return str(storage["value"]) def page_version(page: dict[str, Any]) -> int: version = page.get("version") if not isinstance(version, dict) or not isinstance(version.get("number"), int): fail("confluence_version_invalid") return int(version["number"]) def strip_storage_tags(value: str) -> str: without_tags = re.sub(r"<[^>]+>", "", value) return re.sub(r"\s+", " ", html.unescape(without_tags)).strip() def managed_section_bounds(storage_body: str) -> tuple[int, int]: heading_pattern = re.compile( r"]*>.*?", re.IGNORECASE | re.DOTALL ) headings = list(heading_pattern.finditer(storage_body)) matches = [ item for item in headings if strip_storage_tags(item.group(0)) == MANAGED_HEADING ] if len(matches) != 1: fail("confluence_managed_heading_invalid") current = matches[0] current_level = int(current.group(1)) end = len(storage_body) for candidate in headings: if ( candidate.start() > current.start() and int(candidate.group(1)) <= current_level ): end = candidate.start() break return current.start(), end def managed_section(mapping_rows: list[dict[str, str]], synchronized_at: str) -> str: parts = [f"

{html.escape(MANAGED_HEADING)}

", ""] parts.extend(f"" for header in TABLE_HEADERS) parts.append("") for item in sorted(mapping_rows, key=lambda row: row["principal_ref"]): values = ( item["principal_ref"], item["principal_alias"], item["token_ref"], "active", synchronized_at, ) parts.append("") parts.extend(f"" for value in values) parts.append("") parts.append("
{html.escape(header)}
{html.escape(value)}
") return "".join(parts) def replace_managed_section(storage_body: str, replacement: str) -> str: if not storage_body.strip(): return replacement start, end = managed_section_bounds(storage_body) return storage_body[:start] + replacement + storage_body[end:] class TableParser(HTMLParser): def __init__(self) -> None: super().__init__() self.rows: list[list[str]] = [] self.current_row: list[str] | None = None self.current_cell: list[str] | None = None def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None: del attrs if tag.lower() == "tr": self.current_row = [] elif tag.lower() in {"td", "th"} and self.current_row is not None: self.current_cell = [] def handle_data(self, data: str) -> None: if self.current_cell is not None: self.current_cell.append(data) def handle_endtag(self, tag: str) -> None: lowered = tag.lower() if ( lowered in {"td", "th"} and self.current_cell is not None and self.current_row is not None ): self.current_row.append( re.sub(r"\s+", " ", "".join(self.current_cell)).strip() ) self.current_cell = None elif lowered == "tr" and self.current_row is not None: self.rows.append(self.current_row) self.current_row = None def parse_managed_table(storage_body: str) -> list[tuple[str, str, str, str, str]]: start, end = managed_section_bounds(storage_body) section = storage_body[start:end] if "iop_" in section or re.search( r"(? None: records = parse_managed_table(storage_body) expected = { (item["principal_ref"], item["principal_alias"], item["token_ref"], "active") for item in mapping_rows } actual = {record[:4] for record in records} if len(records) != len(mapping_rows) or actual != expected: fail("confluence_table_mismatch") def ensure_create_preserves_rows( existing_records: list[tuple[str, str, str, str, str]], mapping_rows: list[dict[str, str]], ) -> None: expected_principals = {item["principal_ref"] for item in mapping_rows} existing_principals = {record[0] for record in existing_records} if not existing_principals.issubset(expected_principals): fail("confluence_create_would_remove_user") def page_in_folder(client: ConfluenceClient, page: dict[str, Any]) -> bool: parent_id = str(page.get("parentId") or "") parent_type = str(page.get("parentType") or "") seen: set[tuple[str, str]] = set() for _ in range(20): if parent_id == CONFLUENCE_FOLDER_ID: return True if not parent_id or (parent_type, parent_id) in seen: return False seen.add((parent_type, parent_id)) if parent_type == "page": parent = client.request( "GET", f"/wiki/api/v2/pages/{urllib.parse.quote(parent_id)}" ) else: parent = client.request( "GET", f"/wiki/api/v2/folders/{urllib.parse.quote(parent_id)}" ) parent_id = str(parent.get("parentId") or "") parent_type = str(parent.get("parentType") or "") return False def exact_title_pages(client: ConfluenceClient, space_id: str) -> list[dict[str, Any]]: query = urllib.parse.urlencode( { "space-id": space_id, "title": CONFLUENCE_TITLE, "status": "current", "limit": 250, } ) next_url: str | None = f"/wiki/api/v2/pages?{query}" matches: list[dict[str, Any]] = [] while next_url: response = client.request("GET", next_url) results = response.get("results") if not isinstance(results, list): fail("confluence_search_invalid") for result in results: if ( isinstance(result, dict) and result.get("title") == CONFLUENCE_TITLE and result.get("status") == "current" ): matches.append(result) links = response.get("_links") next_value = links.get("next") if isinstance(links, dict) else None next_url = str(next_value) if next_value else None return matches def preflight_confluence( root: Path, client: ConfluenceClient, target_cache: Path, *, read_only: bool, ) -> dict[str, Any]: client.request("GET", "/wiki/rest/api/user/current") folder = client.request("GET", f"/wiki/api/v2/folders/{CONFLUENCE_FOLDER_ID}") space_id = str(folder.get("spaceId") or "") if not space_id: fail("confluence_space_invalid") candidates = exact_title_pages(client, space_id) valid: list[dict[str, Any]] = [] for page_candidate in candidates: page_id = str(page_candidate.get("id") or "") if not page_id: continue detail = client.request( "GET", f"/wiki/api/v2/pages/{urllib.parse.quote(page_id)}?body-format=storage", ) if page_in_folder(client, detail): valid.append(detail) if len(valid) > 1: fail("confluence_target_ambiguous") if not valid: if read_only: fail("confluence_target_missing") initial = managed_section( [], time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()) ) created = client.request( "POST", "/wiki/api/v2/pages", { "spaceId": space_id, "status": "current", "title": CONFLUENCE_TITLE, "parentId": CONFLUENCE_FOLDER_ID, "body": {"representation": "storage", "value": initial}, }, ) page_id = str(created.get("id") or "") if not page_id: fail("confluence_create_invalid") valid = [ client.request("GET", f"/wiki/api/v2/pages/{page_id}?body-format=storage") ] if not page_in_folder(client, valid[0]): fail("confluence_parent_invalid") page = valid[0] if page.get("title") != CONFLUENCE_TITLE or page.get("status") != "current": fail("confluence_target_invalid") confluence_storage(page) page_version(page) if not read_only: canonical = ( f"{ATLASSIAN_BASE_URL}/wiki/spaces/Lab2/pages/{page['id']}\n".encode() ) target_candidate = write_candidate(target_cache, canonical) os.replace(target_candidate, target_cache) os.chmod(target_cache, 0o600) require_secure_secret(root, target_cache) return page def table_rows_from_store( store_entries: dict[str, str], remote_mappings: list[dict[str, Any]] ) -> list[dict[str, str]]: rows: list[dict[str, str]] = [] for principal_ref, raw_token in store_entries.items(): matches = [ item for item in remote_mappings if str(item.get("principal_ref")) == principal_ref ] if len(matches) != 1: fail("store_edge_mapping_mismatch") item = matches[0] if sha256_text(raw_token) != str(item.get("token_hash_sha256", "")).lower(): fail("store_edge_hash_mismatch") rows.append( { "principal_ref": principal_ref, "principal_alias": str(item.get("principal_alias", "")), "token_ref": str(item.get("token_ref", "")), } ) if len({row["principal_ref"] for row in rows}) != len(rows): fail("store_edge_mapping_duplicate") return rows def sync_confluence( client: ConfluenceClient, page: dict[str, Any], mapping_rows: list[dict[str, str]], ) -> tuple[int, int]: page_id = str(page.get("id") or "") latest = client.request( "GET", f"/wiki/api/v2/pages/{urllib.parse.quote(page_id)}?body-format=storage" ) if not page_in_folder(client, latest): fail("confluence_parent_invalid") old_version = page_version(latest) old_parent = str(latest.get("parentId") or "") old_title = str(latest.get("title") or "") old_status = str(latest.get("status") or "") if old_title != CONFLUENCE_TITLE or old_status != "current": fail("confluence_target_changed") old_body = confluence_storage(latest) records = parse_managed_table(old_body) ensure_create_preserves_rows(records, mapping_rows) try: verify_managed_table(old_body, mapping_rows) return old_version, len(mapping_rows) except WorkflowFailure as error: if error.code != "confluence_table_mismatch": raise synchronized_at = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()) replacement = managed_section(mapping_rows, synchronized_at) new_body = replace_managed_section(old_body, replacement) client.request( "PUT", f"/wiki/api/v2/pages/{urllib.parse.quote(page_id)}", { "id": page_id, "status": old_status, "title": old_title, "body": {"representation": "storage", "value": new_body}, "version": {"number": old_version + 1}, }, ) verified = client.request( "GET", f"/wiki/api/v2/pages/{urllib.parse.quote(page_id)}?body-format=storage" ) if ( str(verified.get("id")) != page_id or str(verified.get("title")) != old_title or str(verified.get("status")) != old_status or str(verified.get("parentId") or "") != old_parent or page_version(verified) != old_version + 1 ): fail("confluence_reread_mismatch") verify_managed_table(confluence_storage(verified), mapping_rows) return old_version + 1, len(mapping_rows) def api_json( root: Path, profile: dict[str, Any], path: str, raw_token: str, payload: dict[str, Any] | None = None, timeout: int = 30, ) -> dict[str, Any]: method = "POST" if payload is not None else "GET" try: status_code, data = curl_request( root, method, str(profile["openai_base_url"]) + path, [f"Authorization: Bearer {raw_token}", "Content-Type: application/json"], payload, timeout=timeout, ) except CurlTransportFailure: fail("openai_smoke_network_failed") if status_code < 200 or status_code >= 300: fail("openai_smoke_http_failed") try: value = json.loads(data) except json.JSONDecodeError: fail("openai_smoke_response_invalid") if not isinstance(value, dict): fail("openai_smoke_response_invalid") return value def api_smoke(root: Path, profile: dict[str, Any], raw_token: str) -> None: if profile["openai_smoke_transport"] == "ssh-loopback": remote_call( root, profile, {"action": "api-smoke", "raw_token": raw_token}, timeout=135, ) return if profile["openai_smoke_transport"] != "public-https": fail("openai_smoke_transport_invalid") models = api_json(root, profile, "/models", raw_token, timeout=15) if not isinstance(models.get("data"), list) or not models["data"]: fail("openai_models_invalid") response = api_json( root, profile, "/chat/completions", raw_token, { "model": profile["smoke_model"], "messages": [{"role": "user", "content": "Reply with the single word OK."}], "max_tokens": 2048, "temperature": 0, }, timeout=120, ) choices = response.get("choices") if not isinstance(choices, list) or not choices or not isinstance(choices[0], dict): fail("openai_chat_invalid") message = choices[0].get("message") content = message.get("content") if isinstance(message, dict) else None if ( not isinstance(content, str) or not content.strip() or not choices[0].get("finish_reason") ): fail("openai_chat_invalid") def metrics_observed( root: Path, profile: dict[str, Any], token_ref: str ) -> bool | None: if profile["metrics_transport"] == "ssh-loopback": try: result = remote_call( root, profile, {"action": "metrics", "token_ref": token_ref}, timeout=15, ) except WorkflowFailure: return None observed = result.get("observed") return observed if isinstance(observed, bool) else None if profile["metrics_transport"] != "public-http": return None try: with urllib.request.urlopen(str(profile["metrics_url"]), timeout=8) as response: metrics = response.read().decode("utf-8", "replace") except (urllib.error.HTTPError, urllib.error.URLError, TimeoutError): return None return re.search(r'token_ref="' + re.escape(token_ref) + r'"', metrics) is not None def tracked_leak_check(root: Path, raw_token: str) -> None: files = run_quiet(["git", "ls-files", "-z"], cwd=root) if files.returncode != 0: fail("tracked_file_list_failed") needle = raw_token.encode("utf-8") for item in files.stdout.split(b"\0"): if not item: continue path = root / os.fsdecode(item) try: if path.is_file() and needle in path.read_bytes(): fail("raw_token_leak_detected") except OSError: fail("tracked_leak_check_failed") def copy_once_to_clipboard(raw_token: str, root: Path) -> None: copied = run_quiet( ["/usr/bin/pbcopy"], cwd=root, input_bytes=raw_token.encode("utf-8") ) if copied.returncode != 0: fail("clipboard_copy_failed") pasted = run_quiet(["/usr/bin/pbpaste"], cwd=root) if ( pasted.returncode != 0 or hashlib.sha256(pasted.stdout).digest() != hashlib.sha256(raw_token.encode()).digest() ): fail("clipboard_verify_failed") def load_confluence( root: Path, profile: dict[str, Any] ) -> tuple[ConfluenceClient, Path]: token_path = root / "token/.lgu-atlassian-token" username_path = root / str(profile["confluence_user_store"]) target_cache = root / "token/.dev-corp-iop-confluence-target" require_secure_secret(root, token_path) require_secure_secret(root, username_path) token = token_path.read_text(encoding="utf-8").strip() username = username_path.read_text(encoding="utf-8").strip() if not token or "\n" in token or "\r" in token: fail("atlassian_token_invalid") if ( not username or "\n" in username or "\r" in username or not re.fullmatch(r"[^@\s]+@[^@\s]+", username) ): fail("atlassian_user_invalid") if target_cache.exists(): require_secure_secret(root, target_cache) elif not git_is_ignored(root, target_cache): fail("target_cache_ignore_invalid") return ConfluenceClient(root, username, token), target_cache def preflight(request: dict[str, str]) -> dict[str, Any]: root = repo_root() profile = load_profile(root, request["env"]) store_path = root / str(profile["secret_store"]) require_secure_secret(root, store_path, must_exist=False) _store_bytes, store_entries = read_store(store_path) remote = remote_call( root, profile, {"action": "inspect", "refresh_probe": True}, timeout=20, ) mappings = remote.get("mappings") if ( not isinstance(mappings, list) or not remote.get("candidate_shape") or remote.get("refresh_status") != "applied" or not remote.get("healthy") or not remote.get("listener") ): fail("edge_preflight_invalid") remote_mappings = [item for item in mappings if isinstance(item, dict)] confluence_status = "not-applicable" if profile["confluence_enabled"]: client, target_cache = load_confluence(root, profile) page = preflight_confluence(root, client, target_cache, read_only=True) current_rows = table_rows_from_store(store_entries, remote_mappings) ensure_create_preserves_rows( parse_managed_table(confluence_storage(page)), current_rows ) confluence_status = "ready" request_state = ( "existing" if select_existing(request, store_entries, remote_mappings) else "new" ) return { "result": "ready", "mode": "preflight", "environment": request["env"], "edge": "healthy", "confluence": confluence_status, "stored_user_count": len(store_entries), "request_state": request_state, "raw_token_generated": False, } def select_existing( request: dict[str, str], store_entries: dict[str, str], remote_mappings: list[dict[str, Any]], ) -> tuple[dict[str, Any], str] | None: principal_matches = [ item for item in remote_mappings if str(item.get("principal_ref")) == request["principal_ref"] ] ref_matches = [ item for item in remote_mappings if str(item.get("token_ref")) == request["token_ref"] ] local_token = store_entries.get(request["principal_ref"]) if len(principal_matches) > 1 or len(ref_matches) > 1: fail("existing_mapping_ambiguous") if ref_matches and ( not principal_matches or ref_matches[0] is not principal_matches[0] ): fail("token_ref_conflict") if principal_matches: if local_token is None: fail("existing_mapping_missing_local_token") mapping = principal_matches[0] if ( sha256_text(local_token) != str(mapping.get("token_hash_sha256", "")).lower() ): fail("existing_mapping_hash_mismatch") return mapping, local_token if local_token is not None: fail("local_token_missing_edge_mapping") return None def execute(request: dict[str, str]) -> dict[str, Any]: started = time.monotonic() root = repo_root() profile = load_profile(root, request["env"]) store_path = root / str(profile["secret_store"]) require_secure_secret(root, store_path, must_exist=False) old_store_bytes, store_entries = read_store(store_path) client: ConfluenceClient | None = None target_cache: Path | None = None page: dict[str, Any] | None = None print("[1/6] preflight", file=sys.stderr, flush=True) if profile["confluence_enabled"]: client, target_cache = load_confluence(root, profile) page = preflight_confluence(root, client, target_cache, read_only=False) remote = remote_call( root, profile, {"action": "inspect", "refresh_probe": True}, timeout=20, ) mappings_value = remote.get("mappings") if ( not isinstance(mappings_value, list) or not remote.get("candidate_shape") or remote.get("refresh_status") != "applied" or not remote.get("healthy") or not remote.get("listener") ): fail("edge_preflight_invalid") remote_mappings = [item for item in mappings_value if isinstance(item, dict)] if page is not None: current_rows = table_rows_from_store(store_entries, remote_mappings) ensure_create_preserves_rows( parse_managed_table(confluence_storage(page)), current_rows ) existing = select_existing(request, store_entries, remote_mappings) edge_state = "existing-verified" backup_path: str | None = None raw_token: str if existing: mapping, raw_token = existing request["principal_alias"] = str( mapping.get("principal_alias") or request["principal_alias"] ) request["token_ref"] = str(mapping.get("token_ref") or request["token_ref"]) print("[2/6] existing mapping reused", file=sys.stderr, flush=True) else: print("[2/6] token generated in memory", file=sys.stderr, flush=True) raw_token = "iop_" + secrets.token_urlsafe(36) token_hash = sha256_text(raw_token) new_content = old_store_bytes if new_content and not new_content.endswith(b"\n"): new_content += b"\n" new_content += f"{request['principal_ref']}: {raw_token}\n".encode() local_candidate = write_candidate(store_path, new_content) try: print("[3/6] Edge transaction", file=sys.stderr, flush=True) activated = remote_call( root, profile, { "action": "apply", "entry": { "token_ref": request["token_ref"], "token_hash_sha256": token_hash, "principal_ref": request["principal_ref"], "principal_alias": request["principal_alias"], }, }, timeout=90, ) backup_path = str(activated.get("backup_path") or "") if not backup_path: fail("edge_backup_reference_missing") os.replace(local_candidate, store_path) os.chmod(store_path, 0o600) require_secure_secret(root, store_path) edge_state = "activated" except BaseException: if backup_path: rollback = remote_call( root, profile, {"action": "rollback", "backup_path": backup_path}, timeout=70, ) if rollback.get("status") != "rolled_back": fail("edge_rollback_unconfirmed") atomic_restore(store_path, old_store_bytes if old_store_bytes else None) raise finally: local_candidate.unlink(missing_ok=True) print("[4/6] environment API smoke", file=sys.stderr, flush=True) try: api_smoke(root, profile, raw_token) except WorkflowFailure: if backup_path: rollback = remote_call( root, profile, {"action": "rollback", "backup_path": backup_path}, timeout=70, ) if rollback.get("status") != "rolled_back": fail("edge_rollback_unconfirmed") atomic_restore(store_path, old_store_bytes if old_store_bytes else None) raise version: int | None = None confluence_status = "not-applicable" _current_bytes, current_store = read_store(store_path) row_count = len(current_store) if client is not None and page is not None: print("[5/6] Confluence metadata sync", file=sys.stderr, flush=True) current_remote = remote_call(root, profile, {"action": "inspect"}, timeout=20) current_values = current_remote.get("mappings") if not isinstance(current_values, list): fail("edge_mapping_reread_invalid") rows = table_rows_from_store( current_store, [item for item in current_values if isinstance(item, dict)] ) version, row_count = sync_confluence(client, page, rows) confluence_status = "updated" else: print("[5/6] Confluence not applicable", file=sys.stderr, flush=True) print("[6/6] leak check and one-time delivery", file=sys.stderr, flush=True) tracked_leak_check(root, raw_token) require_secure_secret(root, store_path) if target_cache is not None: require_secure_secret(root, target_cache) copy_once_to_clipboard(raw_token, root) observed = metrics_observed(root, profile, request["token_ref"]) return { "result": "completed", "operation": "create", "environment": request["env"], "principal_alias": request["principal_alias"], "token_ref": request["token_ref"], "edge_mapping": edge_state, "api_smoke": "passed", "confluence_metadata_sync": confluence_status, "confluence_version": version, "metadata_row_count": row_count, "metrics_observed": observed, "raw_token_delivered_once": True, "delivery_channel": "local_clipboard", "leak_check": "passed", "elapsed_seconds": round(time.monotonic() - started, 1), } def selftest() -> dict[str, Any]: sample = normalize_alias("A.Name+test@example.invalid", None) if sample != "a-name-test": fail("selftest_alias_failed") if normalize_alias("a@example.invalid", None) != "a": fail("selftest_short_alias_failed") try: parse_request('{"env":"dev","principal_ref":null}') except WorkflowFailure as error: if error.code != "principal_ref_invalid": raise else: fail("selftest_input_type_failed") try: parse_request('{"principal_ref":"sample@example.invalid"}') except WorkflowFailure as error: if error.code != "environment_not_supported": raise else: fail("selftest_environment_required_failed") root = repo_root() dev_request = parse_request( '{"env":"dev","principal_ref":"sample@example.invalid"}' ) corp_request = parse_request( '{"env":"dev-corp","principal_ref":"sample@example.invalid"}' ) if dev_request["token_ref"] != "iop-dev-sample": fail("selftest_dev_token_ref_failed") if corp_request["token_ref"] != "iop-dev-corp-sample": fail("selftest_dev_corp_token_ref_failed") for environment in SUPPORTED_ENVIRONMENTS: profile = load_profile(root, environment) if profile["environment"] != environment: fail("selftest_profile_failed") rows = [ { "principal_ref": "sample@example.invalid", "principal_alias": "sample", "token_ref": "iop-dev-corp-sample", } ] original = "

Intro

Keep

IOP 사용자 토큰 발급 현황

old

Next

Keep too

" replaced = replace_managed_section( original, managed_section(rows, "2026-01-01T00:00:00Z") ) verify_managed_table(replaced, rows) if "

Keep

" not in replaced or "

Keep too

" not in replaced: fail("selftest_section_failed") records = parse_managed_table(replaced) try: ensure_create_preserves_rows(records, []) except WorkflowFailure as error: if error.code != "confluence_create_would_remove_user": raise else: fail("selftest_append_only_failed") helper = ( root / "agent-ops/skills/project/openai-usage-token-issue/scripts/remote_edge_transaction.rb" ) for environment in SUPPORTED_ENVIRONMENTS: ruby = run_quiet( ["ruby", str(helper)], cwd=root, input_bytes=json.dumps( {"action": "selftest", "environment": environment}, separators=(",", ":"), ).encode(), timeout=10, ) parsed = None for line in reversed(ruby.stdout.decode("utf-8", "replace").splitlines()): try: value = json.loads(line) except json.JSONDecodeError: continue if isinstance(value, dict): parsed = value break if ruby.returncode != 0 or not parsed or parsed.get("status") != "ok": fail("selftest_remote_helper_failed") return {"result": "passed", "mode": "self-test", "network_used": False} def main() -> int: parser = argparse.ArgumentParser( description="Issue one dev or dev-corp IOP user token from stdin JSON." ) mode = parser.add_mutually_exclusive_group() mode.add_argument( "--preflight", action="store_true", help="Run read-only live readiness checks." ) mode.add_argument( "--self-test", action="store_true", help="Run local deterministic tests." ) arguments = parser.parse_args() try: if arguments.self_test: result = selftest() else: request = parse_request(sys.stdin.read()) root = repo_root() with local_transaction_lock(root, shared=arguments.preflight): result = preflight(request) if arguments.preflight else execute(request) print(json.dumps(result, ensure_ascii=False, separators=(",", ":"))) return 0 except WorkflowFailure as error: print( json.dumps( { "result": "blocked", "code": error.code, "raw_token_reported": False, "retry_same_command": True, }, ensure_ascii=False, separators=(",", ":"), ) ) return 2 except KeyboardInterrupt: print( json.dumps( { "result": "blocked", "code": "interrupted", "raw_token_reported": False, "retry_same_command": True, }, separators=(",", ":"), ) ) return 130 except Exception: # noqa: BLE001 - never render a traceback that could retain secret request state. print( json.dumps( { "result": "blocked", "code": "unexpected_local_failure", "raw_token_reported": False, "retry_same_command": True, }, separators=(",", ":"), ) ) return 2 if __name__ == "__main__": raise SystemExit(main())