[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6H04BHFJDHP1W42REGPEPYM":3,"skill-same:01M6H04BHFJDHP1W42REGPEPYM":76},{"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":16,"sourceHtmlUrl":17,"categories":18,"keywords":19,"publishedAt":34,"linkOnly":35,"markdownContent":36,"markdownBody":37,"frontMatter":38,"refName":39,"commitSha":40,"skillDirectory":41,"forksCount":42,"repositoryHtmlUrl":43,"repositoryHomepageUrl":6,"ownerHtmlUrl":44,"ownerBlogUrl":45,"ownerDescription":46,"updatedAt":47,"install":48,"resources":61},"01M6H04BHFJDHP1W42REGPEPYM","run-containers-as-a-non-root-user",null,"Use when a container should not have root inside it even if the host is safe. Creates and switches to an unprivileged UID pinned in the image so a process compromise is not a root compromise.","jiayaoqijia\u002Fcryptoskill","jiayaoqijia","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1453879?v=4","01M6GMYTX7Q7S504VC6E756ENR","YQ","01M6GMYV1QKJ1CC75MTTGT9PR0",81,"MIT","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-run-containers-as-a-non-root-user\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-run-containers-as-a-non-root-user\u002FSKILL.md",[],[20,21,22,23,24,25,26,27,28,29,30,31,32,33],"containers","run","user","as","root","run containers as a non root user","image","safe","process","use","container","host","it","when","2026-11-10 10:12:30",false,"---\nname: run-containers-as-a-non-root-user\ndescription: Use when a container should not have root inside it even if the host is safe. Creates and switches to an unprivileged UID pinned in the image so a process compromise is not a root compromise.\n---\n\n# Run Containers as a Non-Root User\n\nBy default a container runs as UID 0, and without a user namespace that is host root for many escape and volume paths. The fix is a numeric, explicit UID baked into the image plus a runtime refusal to run as root.\n\n## Procedure\n\n1. Create the user in the image with a fixed numeric UID (names are resolved in the image, so a bare `USER app` fails on a base that lacks the passwd entry):\n   ```dockerfile\n   RUN groupadd -g 10001 app && useradd -u 10001 -g 10001 -m -s \u002Fsbin\u002Fnologin app\n   USER 10001:10001\n   ```\n2. `chown` the working dir and any writable paths before switching, since root-only writes after `USER` fail:\n   `RUN chown -R 10001:10001 \u002Fapp && chmod -R u+rwX \u002Fapp`.\n3. At runtime, make the intent explicit and defensive:\n   `docker run --user 10001:10001 --read-only --tmpfs \u002Ftmp app:x`.\n4. In Kubernetes set `runAsNonRoot: true` and a numeric `runAsUser`, which the kubelet refuses to violate:\n   ```yaml\n   securityContext:\n     runAsNonRoot: true\n     runAsUser: 10001\n     allowPrivilegeEscalation: false\n     capabilities: { drop: [\"ALL\"] }\n   ```\n5. Enforce cluster-wide with the Pod Security Standard `restricted` profile, or a Kyverno rule requiring `runAsNonRoot: true` on every pod.\n6. Check what a process can do: `docker run --rm app:x id` must print `uid=10001`. For ports, bind to `>1024` — non-root cannot bind `80`\u002F`443`, so publish with `-p 8080:8080` and let the proxy handle the low port.\n7. If a supervisor needs a low port, do not grant `CAP_NET_BIND_SERVICE` broadly; drop ALL and add back only that one capability.\n\n## Pitfalls\n\n- Setting `USER` in the Dockerfile does not stop `docker run --user 0`; only `runAsNonRoot: true` in the orchestrator enforces it.\n- A base image's `USER 1000` is often overridden by a later `RUN` that escalates to `USER root` and never switches back — the image ships as root and nobody notices.\n- `chown -R` in a huge layer doubles image size; prefer creating files as the target user or `--chown=10001:10001` on `COPY`.\n- Volume mounts from the host arrive owned by the host's UID; a container non-root user then cannot write them. Set `fsGroup` (K8s) or `--user` matching the host, or use an init container to chown.\n- Random UIDs from `runAsUser` ranges break images whose entrypoint reads `\u002Fetc\u002Fpasswd` for a home directory; mount a writable `HOME` or an emptyDir instead.\n- `allowPrivilegeEscalation: false` still permits a setuid binary already in the image — remove setuid bits in the Dockerfile (`RUN find \u002F -perm -4000 -exec chmod u-s {} +`).\n\n## Verification\n\n    docker run --rm app:x id\n    # uid=10001(app) gid=10001(app) groups=10001(app)\n\nThe command prints a non-zero UID and the container runs its healthcheck without permission errors. Report the observed UID\u002FGID and the policy that enforced it.\n","# Run Containers as a Non-Root User\n\nBy default a container runs as UID 0, and without a user namespace that is host root for many escape and volume paths. The fix is a numeric, explicit UID baked into the image plus a runtime refusal to run as root.\n\n## Procedure\n\n1. Create the user in the image with a fixed numeric UID (names are resolved in the image, so a bare `USER app` fails on a base that lacks the passwd entry):\n   ```dockerfile\n   RUN groupadd -g 10001 app && useradd -u 10001 -g 10001 -m -s \u002Fsbin\u002Fnologin app\n   USER 10001:10001\n   ```\n2. `chown` the working dir and any writable paths before switching, since root-only writes after `USER` fail:\n   `RUN chown -R 10001:10001 \u002Fapp && chmod -R u+rwX \u002Fapp`.\n3. At runtime, make the intent explicit and defensive:\n   `docker run --user 10001:10001 --read-only --tmpfs \u002Ftmp app:x`.\n4. In Kubernetes set `runAsNonRoot: true` and a numeric `runAsUser`, which the kubelet refuses to violate:\n   ```yaml\n   securityContext:\n     runAsNonRoot: true\n     runAsUser: 10001\n     allowPrivilegeEscalation: false\n     capabilities: { drop: [\"ALL\"] }\n   ```\n5. Enforce cluster-wide with the Pod Security Standard `restricted` profile, or a Kyverno rule requiring `runAsNonRoot: true` on every pod.\n6. Check what a process can do: `docker run --rm app:x id` must print `uid=10001`. For ports, bind to `>1024` — non-root cannot bind `80`\u002F`443`, so publish with `-p 8080:8080` and let the proxy handle the low port.\n7. If a supervisor needs a low port, do not grant `CAP_NET_BIND_SERVICE` broadly; drop ALL and add back only that one capability.\n\n## Pitfalls\n\n- Setting `USER` in the Dockerfile does not stop `docker run --user 0`; only `runAsNonRoot: true` in the orchestrator enforces it.\n- A base image's `USER 1000` is often overridden by a later `RUN` that escalates to `USER root` and never switches back — the image ships as root and nobody notices.\n- `chown -R` in a huge layer doubles image size; prefer creating files as the target user or `--chown=10001:10001` on `COPY`.\n- Volume mounts from the host arrive owned by the host's UID; a container non-root user then cannot write them. Set `fsGroup` (K8s) or `--user` matching the host, or use an init container to chown.\n- Random UIDs from `runAsUser` ranges break images whose entrypoint reads `\u002Fetc\u002Fpasswd` for a home directory; mount a writable `HOME` or an emptyDir instead.\n- `allowPrivilegeEscalation: false` still permits a setuid binary already in the image — remove setuid bits in the Dockerfile (`RUN find \u002F -perm -4000 -exec chmod u-s {} +`).\n\n## Verification\n\n    docker run --rm app:x id\n    # uid=10001(app) gid=10001(app) groups=10001(app)\n\nThe command prints a non-zero UID and the container runs its healthcheck without permission errors. Report the observed UID\u002FGID and the policy that enforced it.\n",{"name":5,"description":7},"main","3df1d0d67b30ff15236561f8c0f9f06d33f42dfd","skills\u002Fpayments\u002F0xklen-run-containers-as-a-non-root-user",17,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia","https:\u002F\u002Feth2030.com","Hardcore infra. Building @alt-research and applied cryptography.","2026-11-12 02:28:42",{"source":8,"skillName":5,"commands":49,"prompt":59,"zipAvailable":60},[50,53,56],{"tool":51,"command":52},"npx","npx skills add jiayaoqijia\u002Fcryptoskill --skill run-containers-as-a-non-root-user",{"tool":54,"command":55},"bunx","bunx skills add jiayaoqijia\u002Fcryptoskill --skill run-containers-as-a-non-root-user",{"tool":57,"command":58},"pnpm","pnpm dlx skills add jiayaoqijia\u002Fcryptoskill --skill run-containers-as-a-non-root-user","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-run-containers-as-a-non-root-user\u002FSKILL.md",true,[62,66,72],{"path":63,"resourceType":63,"resourceTypeDesc":64,"sizeBytes":65,"sourceHtmlUrl":16},"LICENSE","许可证",1063,{"path":67,"resourceType":68,"resourceTypeDesc":69,"sizeBytes":70,"sourceHtmlUrl":71},"SOURCE.md","REFERENCE","参考文档",359,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-run-containers-as-a-non-root-user\u002FSOURCE.md",{"path":73,"resourceType":68,"resourceTypeDesc":69,"sizeBytes":74,"sourceHtmlUrl":75},"TRUST.auto.yaml",2217,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-run-containers-as-a-non-root-user\u002FTRUST.auto.yaml",[77,105,128,146,159,169],{"skillNo":78,"name":79,"nameZh":6,"description":80,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":81,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":34},"01M712C436EQYE43342Q4E7GG1","recipe-performance","Diagnose a specific MetaMask user flow's real-app performance and Sentry critical-user-flow telemetry with deterministic mm-harness recipes. Use for CUF boundaries, cold\u002Fwarm\u002Fbackground-resume behavior, latency regressions, lifecycle tags, duplicate or blocking network requests, long tasks, layout\u002Fpaint cost, screen redraws, React rerenders, or browser trace analysis where tests alone cannot prove the real app.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FSKILL.md",[],[85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104],"performance","recipe performance","recipe","mm","sentry","harness","app","deterministic","recipes","flow","cold","critical","analysis","tasks","react","browser","layout","screen","network","metamask",{"skillNo":106,"name":107,"nameZh":6,"description":108,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":109,"licenseFileUrl":110,"sourceHtmlUrl":111,"categories":112,"keywords":113,"publishedAt":34},"01M70XT2F8A5CQZ81JBP98KSW3","mexc-spot-websocket","MEXC Spot WebSocket workflows for public streams, protobuf handling, depth maintenance, listen keys, and private streams without exposing API keys.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FSKILL.md",[],[114,115,116,117,118,119,120,121,122,123,124,125,126,127],"mexc spot websocket","spot","websocket","api","workflows","public","listen","streams","depth","keys","for","api keys","maintenance","protobuf",{"skillNo":129,"name":130,"nameZh":6,"description":131,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":109,"licenseFileUrl":132,"sourceHtmlUrl":133,"categories":134,"keywords":135,"publishedAt":34},"01M70XT0MBXN3WZY1BKN0CPNKR","mexc-spot-rest","MEXC Spot REST workflows for public data, signed account requests, orders, wallet\u002Fadmin actions, and secure signing without exposing API keys.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FSKILL.md",[],[136,115,137,138,139,140,141,125,124,123,142,143,144,119,145,118,117],"mexc spot rest","REST","admin","signing","Wallet","requests","actions","secure","data","orders",{"skillNo":147,"name":148,"nameZh":6,"description":149,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":109,"licenseFileUrl":150,"sourceHtmlUrl":151,"categories":152,"keywords":153,"publishedAt":34},"01M70XSYSVZ2N0N91XCAR2CAK0","mexc-futures-websocket","MEXC Futures WebSocket workflows for public streams, private account\u002Forder\u002Fposition streams, ping\u002Fpong, subscriptions, and depth maintenance.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FSKILL.md",[],[154,155,116,156,157,126,124,158,122,121,119,118],"mexc futures websocket","futures","position","ping","subscriptions",{"skillNo":160,"name":161,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":162,"sourceHtmlUrl":163,"categories":164,"keywords":165,"publishedAt":34},"01M6H0ZWHVE5W04WG2DKQE2SQC","0xklen-version-and-refresh-sanctions-lists","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FSKILL.md",[],[166,167,168],"refresh","0xklen version and refresh sanctions lists","version",{"skillNo":170,"name":171,"nameZh":6,"description":172,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":173,"sourceHtmlUrl":174,"categories":175,"keywords":176,"publishedAt":34},"01M6H0Z28Q3R8J0S799GJQWXM3","verify-tests-cover-changed-lines","Use when a PR adds code that the existing suite may not exercise. Measures patch coverage — the share of newly changed lines hit by tests — before approving.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FSKILL.md",[],[177,178,179,180,181,182,183,29,184,185,186],"tests","cover","verify tests cover changed lines","verify","coverage","pr","exercise","patch","code","share"]