# openrouter-secrets: a capsule that uses an API key without ever holding it. # # It adds three things to hello-world: # [network] the one host it may reach, and why (the person reads `why` # before granting it at serve time) # [secrets] the key it needs, by name; never its value # [[secrets.inject]] how m64's gate adds the key to outgoing requests, so the # key stays outside the container schema = "m64/capsule@1" description = "OpenRouter with a secret: a chat endpoint that forwards to a model on OpenRouter. Shows [network], [secrets] and [[secrets.inject]]: your OPENROUTER_API_KEY stays in m64's gate and never enters the container. No GPU." kinds = ["chat"] authors = ["motif42"] license = "mit" [hardware] # CPU only. On an ARM machine use "linux-aarch64" (the image is multi-arch). platform = "linux-x86_64" [runtime] sandbox = "container" # python:3.12-slim (multi-arch index digest); server.py is standard library only. image = "python@sha256:2f17fc044b579bab302c2e8054d3a686e2cb9a83de48e70534b94cd8ebbe06a9" gpu = false internal_port = 9000 health = "/health" expected_load_seconds = 10 model_name = "deepseek-v4.1-flash" user = "65534:65534" # Without this table the capsule has no network at all. With it, the person # still has to grant it: `m64 serve --allow-external-network`. # Every host the code names must be listed here, or `m64 check` blocks the push. [network] needs = ["openrouter.ai:443"] why = "the model runs on OpenRouter: your prompts and its replies go through openrouter.ai" # The capsule needs this secret to start. m64 looks for it in # ~/.config/m64/secrets.env (set it with `m64 config secrets set OPENROUTER_API_KEY`) # or in the file given with --secret-file. A missing secret refuses the serve. [secrets] required = ["OPENROUTER_API_KEY"] # The key never enters the container. server.py calls http://openrouter.ai # (plain http) through $HTTP_PROXY, which is m64's gate. The gate adds # `Authorization: Bearer ` for that host only, then goes on over TLS. # Inside the container, $OPENROUTER_API_KEY holds only a placeholder. [[secrets.inject]] name = "OPENROUTER_API_KEY" host = "openrouter.ai" header = "Authorization" value = "Bearer {secret}"