[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6AD9Q293GYDF752HBPYX0VF":3,"skill-same:01M6AD9Q293GYDF752HBPYX0VF":73},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":49,"commitSha":50,"skillDirectory":51,"forksCount":52,"repositoryHtmlUrl":53,"repositoryHomepageUrl":54,"ownerHtmlUrl":55,"ownerBlogUrl":56,"ownerDescription":57,"updatedAt":58,"install":59,"resources":72},"01M6AD9Q293GYDF752HBPYX0VF","add-llm-provider",null,"Decide and implement how to support a new LLM provider or agent engine in AWF - either as a proxied provider (api-proxy adapter) or a direct-API engine (domain allowlist only), e.g. Cursor, Aider, or any tool that calls its own endpoint.","github\u002Fgh-aw-firewall","github","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F9919?v=4","01M6AC83DS133TPXFSP1DHNCC6","GitHub","01M6AD985Y1G0AQ64JV7KPQWZ4",160,"MIT","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fgh-aw-firewall\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fadd-llm-provider\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"add llm provider","add","provider","new","implement","calls","adapter","how to","as","aider","domain","either","only","decide","engine","tool","how","api","proxy","support","2026-11-10 10:12:30",false,"---\nname: add-llm-provider\ndescription: Decide and implement how to support a new LLM provider or agent engine in AWF - either as a proxied provider (api-proxy adapter) or a direct-API engine (domain allowlist only), e.g. Cursor, Aider, or any tool that calls its own endpoint.\n---\n\n# Add LLM Provider\n\nUse this skill whenever a new agent engine or LLM provider needs to work behind AWF and it is unclear how to \"set it up.\" AWF supports two fundamentally different integration paths — picking the wrong one is the most common source of confusion (e.g. \"why is `token-usage.jsonl` empty for this engine?\").\n\n## Step 1 — Determine how the engine talks to its LLM backend\n\nAsk: **does the engine call the provider's API directly (its own base URL, its own auth), or can it be configured to route through AWF's API-proxy sidecar**? The sidecar is always enabled; `--enable-api-proxy` is deprecated and ignored. Its provider ports are `http:\u002F\u002F172.30.0.30:10000` (OpenAI), `:10001` (Anthropic), `:10002` (Copilot), `:10003` (Gemini), and `:10004` (Vertex AI).\n\n- If the engine has built-in support for pointing at AWF's api-proxy ports (env vars like `OPENAI_BASE_URL`, `ANTHROPIC_BASE_URL` rewritten to the sidecar) → **Path A: Proxied provider**.\n- If the engine always calls its own hardcoded\u002Fnative endpoint regardless of proxy env vars (e.g. Cursor CLI calling `api2.cursor.sh` \u002F `api3.cursor.sh` directly), or manages its own credentials outside AWF → **Path B: Direct-API engine**.\n\nWhen unsure, run the engine once with `--keep-containers` and inspect `docker exec awf-squid cat \u002Fvar\u002Flog\u002Fsquid\u002Faccess.log` (see [docs\u002Fsquid_log_filtering.md](..\u002F..\u002F..\u002Fdocs\u002Fsquid_log_filtering.md)) to see which hosts it actually contacts and whether traffic reaches the api-proxy sidecar or goes straight out through Squid.\n\n## Path A — Proxied provider (credentials injected by api-proxy)\n\nChoose this when you want AWF to hold the API key\u002FOIDC token and inject it, keeping secrets out of the agent container.\n\nUse **[containers\u002Fapi-proxy\u002Fproviders\u002FADDING-A-PROVIDER.md](..\u002F..\u002F..\u002Fcontainers\u002Fapi-proxy\u002Fproviders\u002FADDING-A-PROVIDER.md)** for the adapter interface, then:\n\n1. Create `containers\u002Fapi-proxy\u002Fproviders\u002F\u003Cname>.js` implementing the `ProviderAdapter` interface.\n2. Register it in `containers\u002Fapi-proxy\u002Fproviders\u002Findex.js`.\n3. Add its port to `src\u002Fconfig\u002Fsandbox-network-policy.json`, then extend the closed `NetworkPolicy` shape and validation in `src\u002Fconfig\u002Fnetwork-policy.ts` and the compatibility mapping in `src\u002Ftypes\u002Fports.ts`. Add it to the Dockerfile `EXPOSE` list; the whole `providers\u002F` directory is already copied. `src\u002Fhost-iptables-rules.ts` consumes `Object.values(API_PROXY_PORTS)`, so it normally needs no change.\n4. Add each credential to the API-proxy environment pipeline in `src\u002Fservices\u002Fapi-proxy-env-config.ts` and explicitly exclude it from agent passthrough in `src\u002Fservices\u002Fagent-environment\u002Fexcluded-vars.ts`; never forward a provider credential generically or from `src\u002Fdocker-manager.ts`.\n5. Add the upstream domain(s) to the allowlist wherever the caller configures `--allow-domains` (AWF itself does not hardcode per-provider domains).\n6. Document auth details in [docs\u002Fauth-matrix.md](..\u002F..\u002F..\u002Fdocs\u002Fauth-matrix.md) if it's a net-new auth pattern.\n7. Write adapter unit tests (`providers\u002F\u003Cname>.test.js`) and run `cd containers\u002Fapi-proxy && npm test -- providers\u002F\u003Cname>.test.js`.\n\n## Path B — Direct-API engine (no proxy adapter needed)\n\nChoose this when the engine calls its own API directly and either manages its own credentials, or credential injection isn't feasible\u002Fneeded through AWF.\n\n1. **No API-proxy adapter is required.** The API proxy remains enabled, but do not try to force an engine through it when it cannot use the sidecar.\n2. **Just allowlist the domain(s)** the engine needs, either via the CLI flag or config file:\n   ```bash\n   awf --allow-domains api2.cursor.sh,api3.cursor.sh -- cursor-agent ...\n   ```\n   or in the AWF config file under `network.allowDomains` (see [docs\u002Fawf-config-spec.md](..\u002F..\u002F..\u002Fdocs\u002Fawf-config-spec.md) and [docs\u002Fawf-config.schema.json](..\u002F..\u002F..\u002Fdocs\u002Fawf-config.schema.json)).\n3. If the engine requires its API key in the agent environment, it cannot receive API-proxy credential isolation. Pass only a minimally scoped credential by an intentional mechanism appropriate to the caller, and do **not** use `sensitiveAllowedDomains` for the key: that setting only redacts secret-derived endpoint hostnames in logs and audit artifacts.\n4. **Telemetry caveat:** because traffic never passes through the API-proxy sidecar, AWF's `token-usage.jsonl` \u002F token-tracking metrics will stay empty for this engine. Any downstream check that assumes all engines produce proxy telemetry (e.g. a \"token usage present\" CI gate) must exclude direct-API engines instead of trying to make them populate it.\n5. Confirm the domains are correct by testing with `--keep-containers` and checking Squid's access log for `TCP_DENIED` entries, then iterating on the allowlist (see [docs\u002Fquickstart.md](..\u002F..\u002F..\u002Fdocs\u002Fquickstart.md) \"Test Domain Blocking\" section).\n\n## Checklist\n\n- [ ] Identified whether the engine is proxied (Path A) or direct-API (Path B)\n- [ ] Path A: adapter created and registered; network policy, credential isolation, image port, and tests updated\n- [ ] Path B: domain(s) allowlisted, telemetry-dependent checks updated to exclude this engine\n- [ ] Verified with `--keep-containers` + Squid access log that the engine's real traffic is allowed and nothing extraneous is\n","# Add LLM Provider\n\nUse this skill whenever a new agent engine or LLM provider needs to work behind AWF and it is unclear how to \"set it up.\" AWF supports two fundamentally different integration paths — picking the wrong one is the most common source of confusion (e.g. \"why is `token-usage.jsonl` empty for this engine?\").\n\n## Step 1 — Determine how the engine talks to its LLM backend\n\nAsk: **does the engine call the provider's API directly (its own base URL, its own auth), or can it be configured to route through AWF's API-proxy sidecar**? The sidecar is always enabled; `--enable-api-proxy` is deprecated and ignored. Its provider ports are `http:\u002F\u002F172.30.0.30:10000` (OpenAI), `:10001` (Anthropic), `:10002` (Copilot), `:10003` (Gemini), and `:10004` (Vertex AI).\n\n- If the engine has built-in support for pointing at AWF's api-proxy ports (env vars like `OPENAI_BASE_URL`, `ANTHROPIC_BASE_URL` rewritten to the sidecar) → **Path A: Proxied provider**.\n- If the engine always calls its own hardcoded\u002Fnative endpoint regardless of proxy env vars (e.g. Cursor CLI calling `api2.cursor.sh` \u002F `api3.cursor.sh` directly), or manages its own credentials outside AWF → **Path B: Direct-API engine**.\n\nWhen unsure, run the engine once with `--keep-containers` and inspect `docker exec awf-squid cat \u002Fvar\u002Flog\u002Fsquid\u002Faccess.log` (see [docs\u002Fsquid_log_filtering.md](..\u002F..\u002F..\u002Fdocs\u002Fsquid_log_filtering.md)) to see which hosts it actually contacts and whether traffic reaches the api-proxy sidecar or goes straight out through Squid.\n\n## Path A — Proxied provider (credentials injected by api-proxy)\n\nChoose this when you want AWF to hold the API key\u002FOIDC token and inject it, keeping secrets out of the agent container.\n\nUse **[containers\u002Fapi-proxy\u002Fproviders\u002FADDING-A-PROVIDER.md](..\u002F..\u002F..\u002Fcontainers\u002Fapi-proxy\u002Fproviders\u002FADDING-A-PROVIDER.md)** for the adapter interface, then:\n\n1. Create `containers\u002Fapi-proxy\u002Fproviders\u002F\u003Cname>.js` implementing the `ProviderAdapter` interface.\n2. Register it in `containers\u002Fapi-proxy\u002Fproviders\u002Findex.js`.\n3. Add its port to `src\u002Fconfig\u002Fsandbox-network-policy.json`, then extend the closed `NetworkPolicy` shape and validation in `src\u002Fconfig\u002Fnetwork-policy.ts` and the compatibility mapping in `src\u002Ftypes\u002Fports.ts`. Add it to the Dockerfile `EXPOSE` list; the whole `providers\u002F` directory is already copied. `src\u002Fhost-iptables-rules.ts` consumes `Object.values(API_PROXY_PORTS)`, so it normally needs no change.\n4. Add each credential to the API-proxy environment pipeline in `src\u002Fservices\u002Fapi-proxy-env-config.ts` and explicitly exclude it from agent passthrough in `src\u002Fservices\u002Fagent-environment\u002Fexcluded-vars.ts`; never forward a provider credential generically or from `src\u002Fdocker-manager.ts`.\n5. Add the upstream domain(s) to the allowlist wherever the caller configures `--allow-domains` (AWF itself does not hardcode per-provider domains).\n6. Document auth details in [docs\u002Fauth-matrix.md](..\u002F..\u002F..\u002Fdocs\u002Fauth-matrix.md) if it's a net-new auth pattern.\n7. Write adapter unit tests (`providers\u002F\u003Cname>.test.js`) and run `cd containers\u002Fapi-proxy && npm test -- providers\u002F\u003Cname>.test.js`.\n\n## Path B — Direct-API engine (no proxy adapter needed)\n\nChoose this when the engine calls its own API directly and either manages its own credentials, or credential injection isn't feasible\u002Fneeded through AWF.\n\n1. **No API-proxy adapter is required.** The API proxy remains enabled, but do not try to force an engine through it when it cannot use the sidecar.\n2. **Just allowlist the domain(s)** the engine needs, either via the CLI flag or config file:\n   ```bash\n   awf --allow-domains api2.cursor.sh,api3.cursor.sh -- cursor-agent ...\n   ```\n   or in the AWF config file under `network.allowDomains` (see [docs\u002Fawf-config-spec.md](..\u002F..\u002F..\u002Fdocs\u002Fawf-config-spec.md) and [docs\u002Fawf-config.schema.json](..\u002F..\u002F..\u002Fdocs\u002Fawf-config.schema.json)).\n3. If the engine requires its API key in the agent environment, it cannot receive API-proxy credential isolation. Pass only a minimally scoped credential by an intentional mechanism appropriate to the caller, and do **not** use `sensitiveAllowedDomains` for the key: that setting only redacts secret-derived endpoint hostnames in logs and audit artifacts.\n4. **Telemetry caveat:** because traffic never passes through the API-proxy sidecar, AWF's `token-usage.jsonl` \u002F token-tracking metrics will stay empty for this engine. Any downstream check that assumes all engines produce proxy telemetry (e.g. a \"token usage present\" CI gate) must exclude direct-API engines instead of trying to make them populate it.\n5. Confirm the domains are correct by testing with `--keep-containers` and checking Squid's access log for `TCP_DENIED` entries, then iterating on the allowlist (see [docs\u002Fquickstart.md](..\u002F..\u002F..\u002Fdocs\u002Fquickstart.md) \"Test Domain Blocking\" section).\n\n## Checklist\n\n- [ ] Identified whether the engine is proxied (Path A) or direct-API (Path B)\n- [ ] Path A: adapter created and registered; network policy, credential isolation, image port, and tests updated\n- [ ] Path B: domain(s) allowlisted, telemetry-dependent checks updated to exclude this engine\n- [ ] Verified with `--keep-containers` + Squid access log that the engine's real traffic is allowed and nothing extraneous is\n",{"name":5,"description":7},"main","564491e648e022be04aa96b73c1681f13f7544f8",".github\u002Fskills\u002Fadd-llm-provider",83,"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fgh-aw-firewall","https:\u002F\u002Fgithub.github.com\u002Fgh-aw-firewall\u002F","https:\u002F\u002Fgithub.com\u002Fgithub","https:\u002F\u002Fgithub.com\u002Fabout","How people build software.","2026-11-13 02:53:04",{"source":8,"skillName":5,"commands":60,"prompt":70,"zipAvailable":71},[61,64,67],{"tool":62,"command":63},"npx","npx skills add github\u002Fgh-aw-firewall --skill add-llm-provider",{"tool":65,"command":66},"bunx","bunx skills add github\u002Fgh-aw-firewall --skill add-llm-provider",{"tool":68,"command":69},"pnpm","pnpm dlx skills add github\u002Fgh-aw-firewall --skill add-llm-provider","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fgithub\u002Fgh-aw-firewall\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fadd-llm-provider\u002FSKILL.md",true,[],[74,110,124,141,167,188],{"skillNo":75,"name":76,"nameZh":6,"description":77,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":78,"categories":79,"keywords":89,"publishedAt":44},"01M6AD9DV31R7XRJ0QZR1MYQPS","awf-skill","Use the AWF (Agentic Workflow Firewall) to run commands with network isolation and domain whitelisting. Provides L7 HTTP\u002FHTTPS egress control for AI agents.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fgh-aw-firewall\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fawf-skill\u002FSKILL.md",[80,83,86],{"categoryNo":81,"categoryName":82,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",{"categoryNo":84,"categoryName":85,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000011","运维与部署",{"categoryNo":87,"categoryName":88,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[90,91,92,93,94,95,96,97,98,99,100,101,102,34,103,104,105,106,107,108,109],"awf skill","agentic workflow","docker","http","workflow","agentic","ai agents","run","https","firewall","read","sudo","isolation","for","use","false","Bash","commands","network","with",{"skillNo":111,"name":76,"nameZh":6,"description":77,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":112,"sourceHtmlUrl":113,"categories":114,"keywords":123,"publishedAt":44},"01M6ADA1AXWT8GAAAZ2MJV1YF1","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fgh-aw-firewall\u002Fblob\u002Fmain\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fgh-aw-firewall\u002Fblob\u002Fmain\u002Fskill.md",[115,116,117,118],{"categoryNo":81,"categoryName":82,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":84,"categoryName":85,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":87,"categoryName":88,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":119,"categoryName":120,"taxonomyType":121,"taxonomyTypeDesc":122},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[90,91,92,93,94,95,96,97,98,99,100,101,102,34,103,104,105,106,107,108,109],{"skillNo":125,"name":126,"nameZh":6,"description":127,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":128,"categories":129,"keywords":130,"publishedAt":44},"01M6AD9ZKQJBHWBVNQEERBCT0V","sandbox-filesystem-access","Configure or diagnose file and directory access, mounts, and host ACLs for AWF sandboxes.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fgh-aw-firewall\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fsandbox-filesystem-access\u002FSKILL.md",[],[131,132,133,134,135,136,137,103,138,139,140],"sandbox","sandbox filesystem access","filesystem","access","diagnose","file","directory","sandboxes","host","configure",{"skillNo":142,"name":143,"nameZh":6,"description":144,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":145,"categories":146,"keywords":147,"publishedAt":44},"01M6AD9XDE32KBEV4V8SXVXQ0D","pr-finisher","Prepare an open pull request for merge from a GitHub Copilot cloud agent. Drives Reviews, local validation, and Mergeable to a ready state. Does not merge, and cannot trigger CI.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fgh-aw-firewall\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fpr-finisher\u002FSKILL.md",[],[148,149,150,151,152,9,153,154,155,156,157,158,159,160,161,162,103,163,164,165,166],"pr finisher","pr","pull","state","github copilot","pull request","merge","ci","validation","copilot","open pull request","cloud","prepare","ready","reviews","trigger","local","open","request",{"skillNo":168,"name":169,"nameZh":6,"description":170,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":171,"categories":172,"keywords":173,"publishedAt":44},"01M6AD9TTKQEWT03YCAPEK28HK","debugging-workflows","Debug GitHub Actions workflows by downloading logs, analyzing summaries, and understanding how agentic workflows and the AWF firewall work together.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fgh-aw-firewall\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fdebugging-workflows\u002FSKILL.md",[],[174,175,176,9,177,178,179,180,95,181,182,99,106,183,40,100,184,185,186,62,187],"debugging workflows","debugging","workflows","actions","github actions","agentic workflows","debug","logs","ls","work","node","analyzing","gh","cat",{"skillNo":189,"name":190,"nameZh":6,"description":191,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":192,"categories":193,"keywords":194,"publishedAt":44},"01M6AD9S2GXF6T58BMN1X7PRHM","agentic-workflows","Route gh-aw design, creation, diagnosis, patching, active debugging, upgrades, and local SDLC issue requests to the right strategies.","https:\u002F\u002Fgithub.com\u002Fgithub\u002Fgh-aw-firewall\u002Fblob\u002Fmain\u002F.github\u002Fskills\u002Fagentic-workflows\u002FSKILL.md",[],[179,176,95,195,175,196,197,198,199,200,201,186,202,203],"design","route","strategies","requests","creation","active","diagnosis","upgrade","patching"]