> ## Documentation Index
> Fetch the complete documentation index at: https://developer.plugchoice.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Security

> What the SDK can and can't do on your users' phones, how secrets travel, and what the hosted flow runs. For your security review.

The SDK is a native shell around the hosted flow at `https://connect.plugchoice.com`. The hosted flow runs the setup; the shell gives it a small, fixed set of native tools for what a web page can't do: join a charger's Wi-Fi, talk to devices on the local network, use Bluetooth, scan a QR code, ask your app for a client secret, and close with a result.

The full contract between the two is the bridge protocol: [`bridge/PROTOCOL.md`](https://github.com/plugchoice/mobile-sdk/blob/main/bridge/PROTOCOL.md). This page sums up what matters for a review.

## Credentials and secrets

| What | Where it lives | Lifetime |
| - | - | - |
| Your integration's client ID and secret | Your server only. Never ship them in your app. | Until you rotate them |
| An access token for the SDK API | Your server, from the client credentials | 1 hour |
| A client secret (`cs_live_…`, `cs_test_…`) | Created by your server, handed to the SDK by your app's callback | 60 minutes to open link sessions |
| A link session | Plugchoice, one per time through Link | At most 6 hours |

* **Scoped.** A client secret reaches only the chargers, sites or address your server named in its `scope`. There's no "everything". See [Client sessions](/sdk/concepts/client-sessions).
* **Random and stored hashed.** A client secret is 32 random bytes. Plugchoice stores only its SHA-256 hash.
* **Never in a URL from the SDK.** The SDK opens the hosted flow with the action in the URL fragment, never the secret. The hosted flow asks the SDK for the secret, and the SDK calls your callback. It never logs the secret and keeps no copy after handing it over.
* **In a browser,** the secret travels in the URL fragment (`#cs=…`), which browsers never send to a server. The hosted flow reads it, then removes it from the address bar, and sends no referrer.

## The hosted flow

* **One origin.** Only pages from `https://connect.plugchoice.com` can use the SDK's native tools.
* **Its own code only.** The page's Content Security Policy allows scripts from its own origin only: no inline or third-party scripts. It sends requests only to its own origin and `api.plugchoice.com`.
* **Never framed.** The page can't be embedded in another site (`frame-ancestors 'none'`, `X-Frame-Options: DENY`).
* **No analytics or telemetry,** in the SDK or in the hosted flow.

## What the native tools can do

<AccordionGroup>
  <Accordion title="Navigation">
    The web view's main frame stays on `https://connect.plugchoice.com`. A link to anywhere else opens in the browser or another app (`http`, `https`, `mailto`, `tel`); any other navigation off the origin is dropped. Subframes load, but can't use the native tools. A reload or a new page cancels everything the previous one started.
  </Accordion>

  <Accordion title="Local network only">
    HTTP, WebSocket, TCP and UDP reach only devices on the local network:

    * IPv4 addresses in `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `169.254.0.0/16` (link-local) and `127.0.0.0/8` (loopback);
    * `::1` and `localhost`;
    * `*.local` names.

    Anything else is refused, so the SDK is never a proxy to the internet. On Android, host names must also resolve to local addresses. HTTP goes without a proxy or a cookie jar, and redirects aren't followed. UDP is unicast only: no multicast or broadcast.
  </Accordion>

  <Accordion title="TLS to devices">
    A device's HTTPS is checked against the system's trust, or against what the hosted flow passes for that device: its maker's certificate authority, or its key's fingerprint. Such a trust can forgive a device certificate's expiry and host name, which some makers let lapse; there's no "accept anything", and the local-network rule still applies.
  </Accordion>

  <Accordion title="Wi-Fi">
    The SDK joins a charger's own setup network, which has no internet, while the setup runs. It never moves your whole app onto that network: your app and the web view keep their internet. The hosted flow has the phone leave the charger's network when that part of the setup is done.
  </Accordion>

  <Accordion title="Bluetooth">
    The SDK talks Bluetooth LE as a client, to devices found by a scan from the same page. At most 8 connections at once; all of them end when the page changes or the screen closes.
  </Accordion>

  <Accordion title="Camera">
    A native scanner reads one QR code, such as a setup code on a charger's card. The SDK never logs what it read.
  </Accordion>

  <Accordion title="Limits">
    One local-network search, one Bluetooth scan and one QR scan at a time; at most 64 HTTP sessions, 16 TCP sockets and 8 Bluetooth connections. Every call has a timeout. The protocol lists them all.
  </Accordion>
</AccordionGroup>

The SDK has no other native tools: the hosted flow can't read files, contacts, photos or your app's data. The SDK knows no charger brands either; everything brand-specific lives in the hosted flow.

## Permissions

* The SDK asks for a permission when the setup needs it, not when your app starts: Wi-Fi, the local network, Bluetooth, the camera, and location (to read the name of the Wi-Fi network).
* On iOS, the prompts use the usage strings in your app's Info.plist. Without the camera or Bluetooth string, the SDK leaves that feature out: the hosted flow offers typing instead of scanning, and doesn't use Bluetooth.
* On Android, the library's manifest declares the permissions; removing the Bluetooth ones turns Bluetooth off. QR scanning uses Google's code scanner from Play services, which sends usage data to Google: mention it in your Play data safety form.

Your platform guide lists every entry: [iOS](/sdk/ios), [Android](/sdk/android), [React Native](/sdk/react-native).

## Dependencies

* **iOS**: none beyond Apple's frameworks.
* **Android**: AndroidX (Activity, Core, WebKit), OkHttp, Kotlin coroutines, and the Google code scanner (Play services).
* **React Native**: the iOS and Android SDKs, through Expo modules.

The SDK is open source: [github.com/plugchoice/mobile-sdk](https://github.com/plugchoice/mobile-sdk).

## Reporting a problem

Email security issues to [security@plugchoice.com](mailto:security@plugchoice.com), not a public GitHub issue. The SDK's [security policy](https://github.com/plugchoice/mobile-sdk/security/policy) says what to include.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.