Android's Network Security Configuration gives an app a declarative place to define how TLS connections are trusted. The file can restrict CAs, add an internal trust anchor, disable cleartext traffic, require certificate transparency, or pin certificates. Those choices are security policy, and they need review in the same way as authentication code.

Start with the trust anchor

Android documents that, by default, secure connections use the pre-installed system CAs. Apps targeting Android 6.0 or lower also trust user-added CAs by default. Modern apps normally do not trust the user store unless a configuration says they do.

A custom trust anchor can be appropriate for a private service. It also narrows the trust decision to a certificate or CA that the team must operate. The Android documentation notes that certificate transparency verification is not performed for connections that use custom trust anchors. That does not make custom CAs insecure. It means the team must compensate with certificate lifecycle controls, monitoring, and a clear reason for the exception.

<network-security-config>
  <base-config cleartextTrafficPermitted="false">
    <trust-anchors>
      <certificates src="system" />
    </trust-anchors>
  </base-config>
  <domain-config>
    <domain includeSubdomains="true">internal.example.invalid</domain>
    <trust-anchors>
      <certificates src="@raw/internal_ca" />
    </trust-anchors>
  </domain-config>
</network-security-config>

The hostname and CA name are illustrative. The trust should be scoped to the domains that actually need it.

Keep debug overrides out of release

The debug-overrides element lets an app trust development CAs only when android:debuggable is true. That is a safer testing workflow than shipping a broad user CA trust in the production configuration. Verify the merged manifest and the packaged XML for release variants, and confirm that the release build is not debuggable.

Pin cautiously. A certificate pin that cannot be rotated can turn a routine certificate change into an outage. If pinning is necessary, define backup pins, an overlap period, and a mechanism to observe client versions before removing the old pin. Review the pinned hostname and the exact certificate or public key.

Test the policy, not just the XML

Run the release app against a valid internal host, an expired certificate, an unexpected public certificate, a user-installed test CA, and a cleartext endpoint. Record which connections succeed. Test debug and release separately because the effective policy can differ.

Check third-party SDK network stacks. Some may use their own trust configuration or bypass the app's expectations. Include the network security config in code review when a dependency adds a domain. A new domain without a policy can be as important as a changed certificate.

The configuration file is small, but it defines the certificate authorities and HTTP conditions the app will accept. Treat each exception as a documented operational commitment with an owner and a removal plan.

References