[{"data":1,"prerenderedAt":277},["ShallowReactive",2],{"docs-page-\u002Fdocs\u002Fapi-keys":3,"docs-surround-\u002Fdocs\u002Fapi-keys":269},{"id":4,"title":5,"body":6,"description":261,"extension":262,"meta":263,"navigation":264,"path":265,"seo":266,"stem":267,"__hash__":268},"docs\u002Fdocs\u002F6.api-keys.md","API Keys",{"type":7,"value":8,"toc":244},"minimark",[9,13,17,22,30,41,46,57,63,74,78,81,113,121,125,128,146,153,161,165,168,172,183,187,190,197,201,204,207,211,224,227,234,238],[10,11,5],"h1",{"id":12},"api-keys",[14,15,16],"p",{},"Your server uses one credential, an API key, which carries two things: a token that authenticates log ingestion requests, and the app's encryption key, which encrypts log content before it leaves your process. It comes from the Lumber app. People signing in to the Lumber app use their own account, which is separate from it.",[18,19,21],"h2",{"id":20},"the-key","The key",[14,23,24,25,29],{},"API keys authenticate your server's log ingestion requests and carry the app's encryption key. Each key is scoped to a single ",[26,27,28],"strong",{},"app"," within your Lumber account. A key is two values joined by a dot: a 32-character hexadecimal token, then the app's base64-encoded encryption key.",[31,32,37],"pre",{"className":33,"code":35,"language":36},[34],"language-text","\u003Ctoken>.\u003CencryptionKey>\n","text",[38,39,35],"code",{"__ignoreMap":40},"",[42,43,45],"h3",{"id":44},"how-it-works","How it works",[14,47,48,49,56],{},"The SDK splits the key at the dot. It encrypts each log with the encryption key, which never leaves your process, and sends it as a ",[50,51,53],"a",{"href":52},"\u002Fdocs\u002Fhttp-api",[38,54,55],{},"POST \u002Flogs"," request to the Lumber API with only the token:",[31,58,61],{"className":59,"code":60,"language":36},[34],"Authorization: Bearer \u003Ctoken>\n",[38,62,60],{"__ignoreMap":40},[14,64,65,66,70,71],{},"The API hashes the token with ",[50,67,69],{"href":68},"\u002Fdocs\u002Fencryption","SHA-256"," and looks up the hash. Only the hash is stored, so the key is shown once, when you create it. ",[26,72,73],{},"If you call the API yourself, send only the part before the dot.",[42,75,77],{"id":76},"creating-a-key","Creating a key",[14,79,80],{},"Creating an app takes you straight to adding its first key. To add another:",[82,83,84,91,100,106],"ol",{},[85,86,87,88],"li",{},"In the Lumber app, open your app, tap the gear, and tap ",[26,89,90],{},"Secrets",[85,92,93,94,96,97],{},"Under ",[26,95,5],{},", tap ",[26,98,99],{},"Add Key",[85,101,102,103],{},"Optionally give it a name, then tap ",[26,104,105],{},"Create",[85,107,108,109,112],{},"Tap ",[26,110,111],{},"Copy & Close",". The key won't be shown again",[14,114,115,116,120],{},"Adding a key needs the app's encryption key on that device, since every key carries it. Each plan allows a set number of API keys per app (one on Hobby). See ",[50,117,119],{"href":118},"\u002F#pricing","pricing",".",[42,122,124],{"id":123},"rotating-keys","Rotating keys",[14,126,127],{},"If your plan allows more than one key per app, create a new key before deleting the old one to avoid downtime:",[82,129,130,133,140,143],{},[85,131,132],{},"Create a new API key in the app",[85,134,135,136,139],{},"Update ",[38,137,138],{},"LUMBER_API_KEY"," in your environment",[85,141,142],{},"Deploy your updated config",[85,144,145],{},"Delete the old key in the app",[14,147,148,149,152],{},"Deleting a key takes effect immediately: requests that still use it get a ",[38,150,151],{},"401"," response. On Hobby, which allows one key per app, delete the old key first and then create the new one.",[14,154,155,156,160],{},"Rotating replaces the token. The new key carries the same encryption key as the old one, since each app has one (see ",[50,157,159],{"href":158},"#key-rotation","Key rotation",").",[42,162,164],{"id":163},"multiple-keys","Multiple keys",[14,166,167],{},"On plans with more than one key per app, you can use separate keys for each environment (staging vs. production) or revoke access for a specific deployment without affecting others.",[18,169,171],{"id":170},"encryption-key","Encryption Key",[14,173,174,175,178,179,182],{},"The encryption key is a ",[26,176,177],{},"32-byte symmetric key",", base64-encoded, used for ",[50,180,181],{"href":68},"AES-256-GCM"," encryption (authenticated encryption, one of the ciphers HTTPS uses). It's the part of each API key after the dot, and the SDK never sends it to the Lumber API.",[42,184,186],{"id":185},"where-it-comes-from","Where it comes from",[14,188,189],{},"When you create an app, the Lumber app generates its encryption key on your device, and every API key you create for the app carries it.",[14,191,192,193,196],{},"The Lumber app keeps the key in your device's secure storage. It only leaves the device wrapped (encrypted) to the account key of a user who has access to the app, using ",[50,194,195],{"href":68},"X25519"," key agreement (the key exchange behind Signal and TLS 1.3) and AES-256-GCM. Lumber's servers store those wrapped copies but cannot decrypt them.",[42,198,200],{"id":199},"sharing-with-your-team","Sharing with your team",[14,202,203],{},"Apps can be shared with the members of your team, or with guests you invite to a single app. Your plan's seat count limits how many members your team can have and how many guests each app can have.",[14,205,206],{},"There's nothing to copy and paste. Whenever someone who already has an app's key opens Lumber, their device wraps the key to the account key of each person with access who doesn't have it yet. Those people's devices then unlock the app automatically the next time they open Lumber.",[42,208,210],{"id":209},"pasting-a-key","Pasting a key",[14,212,213,214,217,218,220,221,223],{},"If a device doesn't have an app's key yet, the app shows a ",[26,215,216],{},"Paste Key"," option. Open the app's ",[26,219,90],{}," screen, tap ",[26,222,216],{},", and paste the API key from your plugin config (or the encryption key on its own). Lumber checks the key against the app's existing logs before saving it, then uploads a copy wrapped to your account key so your other devices get it too.",[42,225,159],{"id":226},"key-rotation",[14,228,229,230,233],{},"Each app has a single encryption key, and the SDK marks every log with ",[38,231,232],{},"keyVersion: 1",". Rotating an app's encryption key isn't supported yet: logs encrypted with one key can't be read with another.",[42,235,237],{"id":236},"losing-the-key","Losing the key",[14,239,240,241],{},"If nobody with access to an app still has its key on a device, and no plugin config still has one of its API keys, the app's logs can't be decrypted. ",[26,242,243],{},"Lumber can't recover the key for you.",{"title":40,"searchDepth":245,"depth":245,"links":246},2,[247,254],{"id":20,"depth":245,"text":21,"children":248},[249,251,252,253],{"id":44,"depth":250,"text":45},3,{"id":76,"depth":250,"text":77},{"id":123,"depth":250,"text":124},{"id":163,"depth":250,"text":164},{"id":170,"depth":245,"text":171,"children":255},[256,257,258,259,260],{"id":185,"depth":250,"text":186},{"id":199,"depth":250,"text":200},{"id":209,"depth":250,"text":210},{"id":226,"depth":250,"text":159},{"id":236,"depth":250,"text":237},"How API keys and the encryption key they carry work in Lumber, and how keys are shared with your team.","md",{},true,"\u002Fdocs\u002Fapi-keys",{"title":5,"description":261},"docs\u002F6.api-keys","FAEh-7vKES2IGWwRGTFRSeAkFdJLzxIkTF8xxKQoreM",[270,274],{"title":271,"path":272,"stem":273,"children":-1},"AI Agents","\u002Fdocs\u002Fmcp","docs\u002F5.mcp",{"title":275,"path":68,"stem":276,"children":-1},"Encryption","docs\u002F7.encryption",1794245210842]