{"slug": "your-coding-agent-is-guessing-your-mobile-app-s-api-give-it-a-redacted-har", "title": "Your coding agent is guessing your mobile app's API. Give it a redacted HAR instead.", "summary": "A developer published a workflow for feeding redacted HTTP Archive (HAR) captures to coding agents debugging mobile apps, arguing that agents otherwise guess at API response shapes they cannot see. The approach routes iOS Simulator, Android emulator, Flutter, and physical iPhone traffic through an HTTPS debugging proxy, then applies a jq filter that restricts the capture to one API host, masks credential-like header, query, and cookie names, and truncates large bodies to 20,000 characters. The developer notes the filter matches on names only, so tokens embedded in JSON bodies can survive, and recommends a grep for JWTs plus a manual read before handing the file to a model.", "body_md": "You ask your coding agent why the orders screen is empty. It reads the client code, reads the model, and then writes a confident fix for a response shape it has never seen. The real response was a `200` with `{\"items\":[],\"error\":\"quota\"}` in the body. Nothing on screen said so, and nothing in the code could.\n\nFor web apps the agent can sometimes look at the browser. For a mobile app it can't see anything unless you give it the traffic. The steps below work with any HTTPS debugging proxy (mitmproxy, or whichever one you already use). Examples assume it listens on `127.0.0.1:8080` and that you've exported its CA certificate.\n\n**iOS Simulator.** The Simulator uses the Mac's network settings, so the Mac's system proxy applies. Trust the CA once per simulator:\n\n```\nxcrun simctl keychain booted add-root-cert ~/proxy-ca.pem\n```\n\nThen restart the app.\n\n**Android emulator.** Start it with the proxy:\n\n```\nemulator -avd Pixel_8 -http-proxy http://127.0.0.1:8080\n```\n\n`127.0.0.1` here is your Mac, because the emulator process applies the flag on the host side. Install the CA as a user certificate. Since Android 7, apps ignore user CAs unless you opt in for debug builds:\n\n``` php\n<!-- res/xml/network_security_config.xml -->\n<network-security-config>\n  <debug-overrides>\n    <trust-anchors>\n      <certificates src=\"user\" />\n    </trust-anchors>\n  </debug-overrides>\n</network-security-config>\n```\n\nReference it from the manifest with `android:networkSecurityConfig=\"@xml/network_security_config\"`. `debug-overrides` only applies to debuggable builds, so release builds stay strict.\n\n**Flutter.** Dart's `HttpClient` ignores the system proxy on every platform. In debug builds, set an `HttpOverrides` whose `findProxy` returns `PROXY <host>:8080`.\n\n**A real iPhone.** Wi-Fi settings → your network → Configure Proxy → Manual, with your Mac's LAN IP and port. Install the CA profile, then switch it on under Settings → General → About → Certificate Trust Settings. Installing the profile alone is not enough.\n\nClear the session, do the one thing that's broken, and export just that as a HAR. A short, focused capture beats an hour of background noise. The agent reads every byte you give it.\n\nA HAR carries everything: bearer tokens, cookies, API keys in query strings. Don't paste that into a model. This jq filter keeps one API host, masks anything that looks like a credential, and truncates very large bodies:\n\n```\n# redact.jq\ndef secret: ascii_downcase | test(\"authorization|cookie|token|secret|api[-_]?key|session|signature|password\");\n.log.entries |= map(select(.request.url | startswith(\"https://api.example.com/\")))\n| .log.entries[] |= (\n    (.request.headers, .response.headers) |= map(if (.name | secret) then .value = \"REDACTED\" else . end)\n  | .request.queryString |= map(if (.name | secret) then .value = \"REDACTED\" else . end)\n  | .request.url |= gsub(\"(?<k>[?&][^=&]*(token|key|secret|sig|session)[^=&]*)=[^&]*\"; \"\\(.k)=REDACTED\"; \"i\")\n  | .request.cookies = [] | .response.cookies = []\n  | .response.content.text |= (if . == null then . else .[:20000] end)\n  )\njq -f redact.jq capture.har > capture.redacted.har\ngrep -oE 'eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+' capture.redacted.har   # leftover JWTs?\n```\n\nThe filter only looks at names. Tokens inside JSON bodies (a login response, a refresh call) still get through, which is what the `grep` is for. Read the file before you hand it over. A sanitized HAR still needs a look.\n\nPut the file in the repo (and in `.gitignore`), then ask something specific:\n\n`capture.redacted.har` has the requests from opening the Orders screen. Which request feeds the list, what did it return, and why does the UI show nothing? Point to the code path.\n\nWhat tends to come back:\n\n`200` responses that carry an error in the body, which the client treats as success.`orderId` vs `order_id`, a number sent as a string), so the whole decode fails silently.\nThis article was created with the help of AI.", "url": "https://wpnews.pro/news/your-coding-agent-is-guessing-your-mobile-app-s-api-give-it-a-redacted-har", "canonical_source": "https://dev.to/minpin_proxy/your-coding-agent-is-guessing-your-mobile-apps-api-give-it-a-redacted-har-instead-1095", "published_at": "2026-11-15 13:09:10+00:00", "updated_at": "2026-11-15 13:19:16.422316+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools"], "entities": ["mitmproxy", "Flutter", "Android", "iOS Simulator", "jq"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/your-coding-agent-is-guessing-your-mobile-app-s-api-give-it-a-redacted-har", "markdown": "https://wpnews.pro/news/your-coding-agent-is-guessing-your-mobile-app-s-api-give-it-a-redacted-har.md", "text": "https://wpnews.pro/news/your-coding-agent-is-guessing-your-mobile-app-s-api-give-it-a-redacted-har.txt", "jsonld": "https://wpnews.pro/news/your-coding-agent-is-guessing-your-mobile-app-s-api-give-it-a-redacted-har.jsonld"}}