{"id":"agent-dockerfile-lint","card_id":"card_agent_dockerfile_lint","name":"Agent Dockerfile lint","description":"Static best-practice lint for supplied Dockerfile text: unpinned bases, curl-pipe-shell, baked-in secrets, root user, ADD misuse, SSH exposure, apt hygiene, and missing HEALTHCHECK.","stage":1,"safety_level":"data_only_read_only","auth":{"type":"hmac-sha256","required_headers":["x-apex-tool-timestamp","x-apex-tool-nonce","x-apex-tool-content-sha256","x-apex-tool-signature"],"canonical_payload":"APEX-TOOL-V1\\n{tool_id}\\n{timestamp}\\n{nonce}\\n{sha256(canonical_json(body))}"},"permissionless":{"enabled":true,"tier":"bounded_public","rate_limit":"Shared 20 calls per IP per hour across permissionless bounded tools plus global agent-write protection","review_required":false,"note":"Anonymous bounded execution is allowed because this lints caller-supplied Dockerfile text (max 200000 chars / 2000 lines) with secret values redacted in findings. No build, no registry lookups, no network, and it never releases source, keys, orders, wallets, private balances, or raw datasets."},"input_schema":{"type":"object","required":["dockerfile"],"properties":{"dockerfile":{"type":"string","maxLength":200000}}},"output_schema":{"type":"object","properties":{"decision":{"type":"string"},"counts":{"type":"object"},"findings":{"type":"array"}}},"sample_input":{"dockerfile":"FROM node:latest\nRUN curl -s https://example.sh | sh\nENV API_TOKEN=abc123"},"test_vectors":[{"input":{"dockerfile":"FROM node:latest\nRUN curl -s https://example.sh | sh\nENV API_TOKEN=abc123"},"expected":{"result":{"decision":"BLOCK","instruction_count":3,"from_count":1,"counts":{"critical":2,"warn":2,"info":1},"secrets_redacted":true,"raw_dockerfile_returned":false}},"match":"subset","verified_at":"2026-07-04T06:30:00.000Z"},{"input":{"dockerfile":"FROM node:20.11-alpine@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\nCOPY package.json ./\nHEALTHCHECK CMD node healthcheck.js\nUSER node"},"expected":{"result":{"decision":"PASS","instruction_count":4,"from_count":1,"counts":{"critical":0,"warn":0,"info":0}}},"match":"subset","verified_at":"2026-07-04T06:30:00.000Z"}]}