[{"data":1,"prerenderedAt":800},["ShallowReactive",2],{"navigation":3,"\u002Fecosystem\u002Fgrants":89,"\u002Fecosystem\u002Fgrants-surround":795},[4,40,63,76],{"title":5,"path":6,"stem":7,"children":8,"icon":39},"Getting Started","\u002Fgetting-started","1.getting-started\u002F1.index",[9,11,15,19,23,27,31,35],{"title":10,"path":6,"stem":7},"Introduction",{"title":12,"path":13,"stem":14},"Quick Start: Service Provider","\u002Fgetting-started\u002Fquickstart-sp","1.getting-started\u002F2.quickstart-sp",{"title":16,"path":17,"stem":18},"Quick Start: Identity Provider","\u002Fgetting-started\u002Fquickstart-idp","1.getting-started\u002F3.quickstart-idp",{"title":20,"path":21,"stem":22},"Quick Start: Agent","\u002Fgetting-started\u002Fquickstart-agent","1.getting-started\u002F4.quickstart-agent",{"title":24,"path":25,"stem":26},"Quick Start","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F5.installation",{"title":28,"path":29,"stem":30},"How It Works","\u002Fgetting-started\u002Fhow-it-works","1.getting-started\u002F6.how-it-works",{"title":32,"path":33,"stem":34},"For Service Providers","\u002Fgetting-started\u002Ffor-service-providers","1.getting-started\u002F7.for-service-providers",{"title":36,"path":37,"stem":38},"CLI (apes & ape-shell)","\u002Fgetting-started\u002Fcli","1.getting-started\u002F8.cli",false,{"title":41,"path":42,"stem":43,"children":44,"icon":39},"Ecosystem","\u002Fecosystem","2.ecosystem\u002F1.index",[45,47,51,55,59],{"title":46,"path":42,"stem":43},"Overview",{"title":48,"path":49,"stem":50},"OpenApe Auth","\u002Fecosystem\u002Fauth","2.ecosystem\u002F2.auth",{"title":52,"path":53,"stem":54},"OpenApe Grants","\u002Fecosystem\u002Fgrants","2.ecosystem\u002F3.grants",{"title":56,"path":57,"stem":58},"nuxt-auth-sp","\u002Fecosystem\u002Fnuxt-auth-sp","2.ecosystem\u002F4.nuxt-auth-sp",{"title":60,"path":61,"stem":62},"escapes","\u002Fecosystem\u002Fescapes","2.ecosystem\u002F5.escapes",{"title":64,"icon":39,"path":65,"stem":66,"children":67,"page":39},"Security","\u002Fsecurity","3.security",[68,72],{"title":69,"path":70,"stem":71},"Compliance","\u002Fsecurity\u002Fcompliance","3.security\u002F1.compliance",{"title":73,"path":74,"stem":75},"Threat Model","\u002Fsecurity\u002Fthreat-model","3.security\u002F2.threat-model",{"title":77,"icon":39,"path":78,"stem":79,"children":80,"page":39},"Guides","\u002Fguides","4.guides",[81,85],{"title":82,"path":83,"stem":84},"Capabilities & Grants","\u002Fguides\u002Fcapabilities","4.guides\u002F1.capabilities",{"title":86,"path":87,"stem":88},"Delegation","\u002Fguides\u002Fdelegation","4.guides\u002F2.delegation",{"id":90,"title":52,"body":91,"description":789,"extension":790,"links":791,"meta":792,"navigation":606,"path":53,"seo":793,"stem":54,"__hash__":794},"docs\u002F2.ecosystem\u002F3.grants.md",{"type":92,"value":93,"toc":776},"minimark",[94,98,103,107,112,123,127,177,181,184,380,383,423,430,440,457,462,524,533,553,560,563,715,719,772],[95,96,52],"h1",{"id":97},"openape-grants",[99,100,102],"h2",{"id":101},"openapegrants","@openape\u002Fgrants",[104,105,106],"p",{},"The permission engine. Framework-agnostic.",[108,109,111],"h3",{"id":110},"grant-lifecycle","Grant Lifecycle",[113,114,119],"pre",{"className":115,"code":117,"language":118},[116],"language-text","Request → Pending → Approved\u002FDenied → (if approved) Active → Used\u002FExpired\u002FRevoked\n","text",[120,121,117],"code",{"__ignoreMap":122},"",[108,124,126],{"id":125},"grant-types","Grant Types",[128,129,130,143],"table",{},[131,132,133],"thead",{},[134,135,136,140],"tr",{},[137,138,139],"th",{},"Type",[137,141,142],{},"Behavior",[144,145,146,157,167],"tbody",{},[134,147,148,154],{},[149,150,151],"td",{},[120,152,153],{},"once",[149,155,156],{},"Single use — consumed after first use",[134,158,159,164],{},[149,160,161],{},[120,162,163],{},"timed",[149,165,166],{},"Valid for a time window (TTL)",[134,168,169,174],{},[149,170,171],{},[120,172,173],{},"always",[149,175,176],{},"Standing permission — active until revoked",[108,178,180],{"id":179},"authz-jwt","AuthZ-JWT",[104,182,183],{},"On approval, a signed AuthZ-JWT is issued:",[113,185,189],{"className":186,"code":187,"language":188,"meta":122,"style":122},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"sub\": \"agent@example.com\",\n  \"aud\": \"target-system\",\n  \"grant_type\": \"once\",\n  \"permissions\": [\"deploy\"],\n  \"cmd_hash\": \"sha256:a1b2c3...\",\n  \"decided_by\": \"alice@example.com\",\n  \"exp\": 1234567890,\n  \"jti\": \"unique-grant-id\"\n}\n","json",[120,190,191,200,228,249,269,294,315,336,354,374],{"__ignoreMap":122},[192,193,196],"span",{"class":194,"line":195},"line",1,[192,197,199],{"class":198},"sMK4o","{\n",[192,201,203,206,210,213,216,219,223,225],{"class":194,"line":202},2,[192,204,205],{"class":198},"  \"",[192,207,209],{"class":208},"spNyl","sub",[192,211,212],{"class":198},"\"",[192,214,215],{"class":198},":",[192,217,218],{"class":198}," \"",[192,220,222],{"class":221},"sfazB","agent@example.com",[192,224,212],{"class":198},[192,226,227],{"class":198},",\n",[192,229,231,233,236,238,240,242,245,247],{"class":194,"line":230},3,[192,232,205],{"class":198},[192,234,235],{"class":208},"aud",[192,237,212],{"class":198},[192,239,215],{"class":198},[192,241,218],{"class":198},[192,243,244],{"class":221},"target-system",[192,246,212],{"class":198},[192,248,227],{"class":198},[192,250,252,254,257,259,261,263,265,267],{"class":194,"line":251},4,[192,253,205],{"class":198},[192,255,256],{"class":208},"grant_type",[192,258,212],{"class":198},[192,260,215],{"class":198},[192,262,218],{"class":198},[192,264,153],{"class":221},[192,266,212],{"class":198},[192,268,227],{"class":198},[192,270,272,274,277,279,281,284,286,289,291],{"class":194,"line":271},5,[192,273,205],{"class":198},[192,275,276],{"class":208},"permissions",[192,278,212],{"class":198},[192,280,215],{"class":198},[192,282,283],{"class":198}," [",[192,285,212],{"class":198},[192,287,288],{"class":221},"deploy",[192,290,212],{"class":198},[192,292,293],{"class":198},"],\n",[192,295,297,299,302,304,306,308,311,313],{"class":194,"line":296},6,[192,298,205],{"class":198},[192,300,301],{"class":208},"cmd_hash",[192,303,212],{"class":198},[192,305,215],{"class":198},[192,307,218],{"class":198},[192,309,310],{"class":221},"sha256:a1b2c3...",[192,312,212],{"class":198},[192,314,227],{"class":198},[192,316,318,320,323,325,327,329,332,334],{"class":194,"line":317},7,[192,319,205],{"class":198},[192,321,322],{"class":208},"decided_by",[192,324,212],{"class":198},[192,326,215],{"class":198},[192,328,218],{"class":198},[192,330,331],{"class":221},"alice@example.com",[192,333,212],{"class":198},[192,335,227],{"class":198},[192,337,339,341,344,346,348,352],{"class":194,"line":338},8,[192,340,205],{"class":198},[192,342,343],{"class":208},"exp",[192,345,212],{"class":198},[192,347,215],{"class":198},[192,349,351],{"class":350},"sbssI"," 1234567890",[192,353,227],{"class":198},[192,355,357,359,362,364,366,368,371],{"class":194,"line":356},9,[192,358,205],{"class":198},[192,360,361],{"class":208},"jti",[192,363,212],{"class":198},[192,365,215],{"class":198},[192,367,218],{"class":198},[192,369,370],{"class":221},"unique-grant-id",[192,372,373],{"class":198},"\"\n",[192,375,377],{"class":194,"line":376},10,[192,378,379],{"class":198},"}\n",[104,381,382],{},"Key security features:",[384,385,386,396,403,410,417],"ul",{},[387,388,389,395],"li",{},[390,391,392,394],"strong",{},[120,393,235],{}," binding"," — token only valid for the intended target",[387,397,398,402],{},[390,399,400],{},[120,401,301],{}," — binds to exact command (prevents substitution attacks)",[387,404,405,409],{},[390,406,407],{},[120,408,322],{}," — dual accountability (agent owner ≠ approver)",[387,411,412,416],{},[390,413,414],{},[120,415,361],{}," — replay protection",[387,418,419,422],{},[390,420,421],{},"Expiry"," — all grants have a maximum lifetime",[99,424,426,427],{"id":425},"grant-routes-in-openapenuxt-auth-idp","Grant Routes in ",[120,428,429],{},"@openape\u002Fnuxt-auth-idp",[104,431,432,433,435,436,439],{},"Grant management is integrated into ",[120,434,429],{},". Enable grant pages with ",[120,437,438],{},"grants.enablePages: true"," in your module config.",[441,442,444],"callout",{"type":443},"warning",[104,445,446,449,450,453,454,456],{},[120,447,448],{},"@openape\u002Fnuxt-grants"," is ",[390,451,452],{},"deprecated",". All grant functionality has been consolidated into ",[120,455,429],{},".",[104,458,459],{},[390,460,461],{},"Auto-registered routes (via nuxt-auth-idp):",[384,463,464,470,476,482,488,494,500,506,512,518],{},[387,465,466,469],{},[120,467,468],{},"\u002Fapi\u002Fgrants"," — list and create grant requests",[387,471,472,475],{},[120,473,474],{},"\u002Fapi\u002Fgrants\u002F:id"," — get grant details",[387,477,478,481],{},[120,479,480],{},"\u002Fapi\u002Fgrants\u002F:id\u002Fapprove"," — approve a grant",[387,483,484,487],{},[120,485,486],{},"\u002Fapi\u002Fgrants\u002F:id\u002Fdeny"," — deny a grant",[387,489,490,493],{},[120,491,492],{},"\u002Fapi\u002Fgrants\u002F:id\u002Frevoke"," — revoke an active grant",[387,495,496,499],{},[120,497,498],{},"\u002Fapi\u002Fgrants\u002F:id\u002Ftoken"," — issue AuthZ-JWT for approved grant",[387,501,502,505],{},[120,503,504],{},"\u002Fapi\u002Fgrants\u002Fverify"," — verify an AuthZ-JWT",[387,507,508,511],{},[120,509,510],{},"\u002Fapi\u002Fagent\u002Fenroll"," — register a new agent",[387,513,514,517],{},[120,515,516],{},"\u002Fapi\u002Fagent\u002Fchallenge"," — request auth challenge",[387,519,520,523],{},[120,521,522],{},"\u002Fapi\u002Fagent\u002Fauthenticate"," — authenticate with signed challenge",[104,525,526,529,530,532],{},[390,527,528],{},"Pages"," (overridable, enabled via ",[120,531,438],{},"):",[384,534,535,541,547],{},[387,536,537,540],{},[120,538,539],{},"\u002Fgrants"," — grant dashboard",[387,542,543,546],{},[120,544,545],{},"\u002Fgrant-approval"," — approve\u002Fdeny UI",[387,548,549,552],{},[120,550,551],{},"\u002Fenroll"," — agent enrollment form",[99,554,556,557,559],{"id":555},"openape-escapes-escapes","openape-escapes (",[120,558,60],{},")",[104,561,562],{},"A Rust binary for local privilege elevation via the grant system. Supports multiple agents per machine with user-owned keys.",[113,564,568],{"className":565,"code":566,"language":567,"meta":122,"style":122},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# Install\ncargo build --release\nsudo make install  # installs to \u002Fusr\u002Flocal\u002Fbin\u002Fescapes with setuid\n\n# Enroll an agent (key is generated if it doesn't exist)\nsudo escapes enroll \\\n  --server https:\u002F\u002Fid.example.com \\\n  --agent-email deploy@example.com \\\n  --agent-name web-deploy \\\n  --key \u002Fetc\u002Fopenape\u002Fagent.key\n\n# Use (--grant identifies the authorization)\nescapes --grant \u003Cjwt> --reason \"Security update\" -- apt-get upgrade\n","bash",[120,569,570,576,588,602,608,613,627,637,647,657,665,670,676],{"__ignoreMap":122},[192,571,572],{"class":194,"line":195},[192,573,575],{"class":574},"sHwdD","# Install\n",[192,577,578,582,585],{"class":194,"line":202},[192,579,581],{"class":580},"sBMFI","cargo",[192,583,584],{"class":221}," build",[192,586,587],{"class":221}," --release\n",[192,589,590,593,596,599],{"class":194,"line":230},[192,591,592],{"class":580},"sudo",[192,594,595],{"class":221}," make",[192,597,598],{"class":221}," install",[192,600,601],{"class":574},"  # installs to \u002Fusr\u002Flocal\u002Fbin\u002Fescapes with setuid\n",[192,603,604],{"class":194,"line":251},[192,605,607],{"emptyLinePlaceholder":606},true,"\n",[192,609,610],{"class":194,"line":271},[192,611,612],{"class":574},"# Enroll an agent (key is generated if it doesn't exist)\n",[192,614,615,617,620,623],{"class":194,"line":296},[192,616,592],{"class":580},[192,618,619],{"class":221}," escapes",[192,621,622],{"class":221}," enroll",[192,624,626],{"class":625},"sTEyZ"," \\\n",[192,628,629,632,635],{"class":194,"line":317},[192,630,631],{"class":221},"  --server",[192,633,634],{"class":221}," https:\u002F\u002Fid.example.com",[192,636,626],{"class":625},[192,638,639,642,645],{"class":194,"line":338},[192,640,641],{"class":221},"  --agent-email",[192,643,644],{"class":221}," deploy@example.com",[192,646,626],{"class":625},[192,648,649,652,655],{"class":194,"line":356},[192,650,651],{"class":221},"  --agent-name",[192,653,654],{"class":221}," web-deploy",[192,656,626],{"class":625},[192,658,659,662],{"class":194,"line":376},[192,660,661],{"class":221},"  --key",[192,663,664],{"class":221}," \u002Fetc\u002Fopenape\u002Fagent.key\n",[192,666,668],{"class":194,"line":667},11,[192,669,607],{"emptyLinePlaceholder":606},[192,671,673],{"class":194,"line":672},12,[192,674,675],{"class":574},"# Use (--grant identifies the authorization)\n",[192,677,679,681,684,687,690,693,696,699,701,704,706,709,712],{"class":194,"line":678},13,[192,680,60],{"class":580},[192,682,683],{"class":221}," --grant",[192,685,686],{"class":198}," \u003C",[192,688,689],{"class":221},"jw",[192,691,692],{"class":625},"t",[192,694,695],{"class":198},">",[192,697,698],{"class":221}," --reason",[192,700,218],{"class":198},[192,702,703],{"class":221},"Security update",[192,705,212],{"class":198},[192,707,708],{"class":221}," --",[192,710,711],{"class":221}," apt-get",[192,713,714],{"class":221}," upgrade\n",[108,716,718],{"id":717},"security-model","Security Model",[384,720,721,732,738,744,752,766],{},[387,722,723,726,727,731],{},[390,724,725],{},"Setuid binary"," — starts as root, drops privileges ",[728,729,730],"em",{},"before"," loading the user's key",[387,733,734,737],{},[390,735,736],{},"User-owned keys"," — private keys belong to the user, stored in user-accessible paths",[387,739,740,743],{},[390,741,742],{},"Agent matching"," — public key derived from private key is matched against registered agents in config",[387,745,746,749,750],{},[390,747,748],{},"Privileges re-elevated only"," after valid AuthZ-JWT with matching ",[120,751,301],{},[387,753,754,757,758,761,762,765],{},[390,755,756],{},"Environment sanitized"," — ",[120,759,760],{},"LD_PRELOAD",", ",[120,763,764],{},"PATH"," etc. reset before exec",[387,767,768,771],{},[390,769,770],{},"Audit log"," — every execution logged as JSONL",[773,774,775],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}",{"title":122,"searchDepth":195,"depth":202,"links":777},[778,783,785],{"id":101,"depth":202,"text":102,"children":779},[780,781,782],{"id":110,"depth":230,"text":111},{"id":125,"depth":230,"text":126},{"id":179,"depth":230,"text":180},{"id":425,"depth":202,"text":784},"Grant Routes in @openape\u002Fnuxt-auth-idp",{"id":555,"depth":202,"text":786,"children":787},"openape-escapes (escapes)",[788],{"id":717,"depth":230,"text":718},"Human-in-the-loop permissions for agents.","md",null,{},{"title":52,"description":789},"VhWF4mOPD8IWBqlnGktmagVwb4oWxZndfUXw1byoi9o",[796,798],{"title":48,"path":49,"stem":50,"description":797,"children":-1},"DNS-based identity for humans and agents.",{"title":56,"path":57,"stem":58,"description":799,"children":-1},"Add OpenApe login to any Nuxt app in minutes.",1776885316420]