// Adoption: the ONE time an operator's refresh token enters the mesh, and it enters already sealed. // // The refresh token is read here, on the MANAGER NODE, sealed to that node's PUBLIC sealing key, and // only the sealed box leaves this process (novox/hq ADR 0050). The control plane stores that box via // `licence set-grant` without ever seeing the refresh token in the clear — the same bound every // delivery keeps. This is the counterpart to `refresh/index.js`: adoption seals the first box, refresh // re-seals a rotated one; both use the very anonymous box (`crypto_box_seal`) the mesh seals every // credential with, so the HOST unseals the stored box to mount the cleartext back — this module is // never given a private key and opens nothing. // // MESH_ANTHROPIC_ADOPT_TOKEN_FILE the operator's refresh token, read once and never written out // MESH_MODEL_ACCESS_BIND_FILE the manager holder's bound facts, carrying manager_public_key // MESH_ANTHROPIC_GRANT_OUT where the sealed box is written, for `licence set-grant` import { readFileSync } from "node:fs"; import { seal } from "../sealedbox.js"; import { managerPublicKey, writeSealedGrant } from "../grantfile.js"; function required(name: string): string { const v = process.env[name]; if (!v) throw new Error(`${name} is not set — adoption needs it`); return v; } const refreshToken = readFileSync(required("MESH_ANTHROPIC_ADOPT_TOKEN_FILE"), "utf8").trim(); if (!refreshToken) throw new Error("[anthropic-manager] there is no refresh token to adopt"); // The node's PUBLIC sealing key, delivered by the mesh in the manager holder's bound facts. Public, // so it is safe to hand a module; the private half stays with the host, which is what opens the box. const nodePub = managerPublicKey(required("MESH_MODEL_ACCESS_BIND_FILE")); const sealed = seal(new Uint8Array(Buffer.from(refreshToken, "utf8")), nodePub); writeSealedGrant(required("MESH_ANTHROPIC_GRANT_OUT"), sealed, nodePub); console.error("[anthropic-manager] sealed the refresh token to this node's key; only the host opens it");