Integration / WEAR API LAB

Wearable API consent and security: design for user control

Plan consent as an ongoing user control, with scoped access, secure connection handling, revocation, deletion, and operational checks.

Neon wearable API consent and security card showing a permission shield and connected wearable

A wearable connection begins with permission, but the design work continues long after a user approves access. The application needs to explain what it imports, handle changing permissions, protect credentials, and stop work when the user disconnects. These behaviors should be visible in the product specification before the first production authorization request.

This guide describes an actual connected application's responsibilities using a hypothetical activity diary. WearAPI.com is an independent educational resource. The examples help you plan your own system and complement the wearable API integration overview.

Start with a purpose for every data type

Write a short purpose statement for each proposed import. An activity diary might need completed workout summaries to populate a calendar. That does not automatically justify requesting detailed location traces, sleep records, or every measurement the provider offers. Map each scope to a specific feature that the user can understand.

Separate required and optional access in the product design, taking account of the provider's actual permission model. When scopes cannot be requested individually, explain the package clearly and decide whether that provider still fits the feature. Do not promise granular controls that its authorization flow cannot deliver.

Show the explanation at the decision point: what will be imported, how far back the first import may reach, and where connection settings live. Keep provider authorization distinct from your application's own choices about retention or additional processing. A successful OAuth response does not answer every product permission question.

Use an appropriate OAuth flow

Where a provider supports OAuth, select its documented authorization code flow and evaluate PKCE support. The IETF's OAuth 2.0 Security Best Current Practice, RFC 9700 requires PKCE for public clients and recommends it for confidential clients. It also describes transaction-specific protection and recommends the S256 challenge method. Follow provider documentation alongside that security baseline.

At a high level, the application starts an authorization transaction, the user approves at the provider, and the application receives a code at its registered redirect address. The code exchange proves possession of the corresponding verifier when PKCE is used. The verifier belongs to that transaction; it should not be a fixed value shared across users.

Use a maintained OAuth library and explicitly test callback handling. Keep the expected provider, redirect address, and initiating application session bound to the transaction. Reject mismatches and expired attempts. If required protections are unavailable, resolve that design gap before offering the connection publicly.

Keep secrets out of delivered frontend files

A browser downloads the JavaScript and configuration needed to run a page. Treat everything delivered to it as inspectable by the person using the browser. A client identifier is not the same as a client secret. Renaming a secret, hiding it in minified code, or injecting it during a static build does not make it confidential.

For an integration using a confidential client, keep the client secret and sensitive credential exchanges in an appropriate trusted service. Define who can read that configuration, how it is rotated, and how a suspected exposure disables its use. A public client requires a design appropriate to its inability to keep such a secret.

Store user tokens according to the application's architecture and threat model. Make access explicit and narrow. Avoid copying production credentials into local fixtures, screenshots, support tickets, or analytics events. Review the connection path separately from ordinary marketing pages and documentation assets.

Model the connection lifecycle

Represent states such as pending authorization, connected, temporarily unavailable, permission changed, and disconnected. A single Boolean named “connected” leaves too much unexplained. The application may retain imported records after the provider stops accepting its token, while the user still expects new workouts to appear.

Decide which events move the connection between states and which require a user action. A temporary timeout should not immediately force a new authorization. A confirmed revocation should stop retries that can never succeed. Keep a human-readable explanation aligned with the internal state.

Where refresh tokens are part of the provider's flow, design for concurrent requests, replacement credentials, and failures during updates. Test the actual provider behavior instead of assuming every integration follows the same rotation policy. A recovery procedure should not accidentally restore an older credential after a newer one has been accepted.

Treat changed permissions as ordinary behavior

Build the feature so it remains understandable when optional data is unavailable. For the activity diary, the user may retain workout summaries while withdrawing access to another collection. The calendar should explain its coverage rather than removing unrelated functionality or repeatedly demanding broader access.

Check permission at the point where a job runs, not only when it enters a queue. A background import may wait long enough for the user to disconnect. Give queued work a connection reference and verify that the connection remains eligible before fetching or processing more records.

Keep unavailable, empty, and unauthorized results distinct where the source exposes that distinction. HealthKit deliberately limits what an app can learn about reading permission, so an empty result does not establish that the user denied access. When the source does expose the distinction, preserve it in both the data layer and user interface. Otherwise, describe the result as unavailable without assuming why, so an absence of data does not become an incorrect activity statement.

Specify disconnect and deletion behavior

Define what “disconnect” does in your product: stop new collection, cancel pending jobs, dispose of usable credentials, and update the visible connection state. Use the provider's supported revocation mechanism where applicable. Do not assume that removing a local row automatically withdraws an upstream grant.

Define deletion separately and explain its scope. Imported records, derived summaries, exports, caches, and support attachments can have different storage paths. Maintain an inventory so a deletion workflow can identify the relevant copies. Treat retention choices as explicit product requirements that need appropriate review for the intended deployment.

Test a race between deletion and an in-flight import. One practical design is to mark the connection unavailable immediately, block new writes associated with it, and then complete the deletion work with auditable status. Whatever approach you choose, verify that a delayed worker cannot repopulate data after the user receives confirmation.

Make observability useful without copying payloads

Choose operational fields that answer a troubleshooting question: integration type, operation, response category, elapsed time, retry count, and a deliberately scoped correlation reference. Avoid routine logging of access tokens, authorization headers, complete callback URLs, raw wearable records, or direct personal identifiers.

A correlation reference can still link events, so limit its lifetime and audience according to its purpose. Restrict log access and establish retention for diagnostic systems as well as the main database. Review error reporting tools because an automatic exception capture can include request context that your own logger excludes.

Use synthetic fixtures for ordinary development and demonstrations. When investigating a production issue requires additional information, create a narrowly scoped procedure with a clear reason and access path. More verbose logging should be a deliberate, temporary decision rather than a permanent response to every support problem.

Make choices observable in the interface

Give the connection settings a concrete account of current behavior: connected provider, imported collections, last successful update, and available disconnect or deletion actions. If historical records remain after disconnection, explain that before the action and reflect it afterward. A stopped import should not look like an unexplained failure.

During usability review, ask a participant to stop future collection and then identify which records remain. Watch whether the labels support that task without requiring knowledge of tokens or background workers. Clear controls reduce the gap between what the system technically permits and what the user reasonably believes they selected.

Exercise realistic threats and failures

Threat-model the connection as a set of boundaries: browser to application, application to provider, queue to worker, and support tools to retained records. Ask what an attacker or mistaken operator could access at each boundary. Prioritize concrete paths such as leaked tokens, swapped user references, or overly broad support access.

Include cross-account tests. A worker receiving an internal user reference must not accept an unrelated provider connection simply because both records exist. Test authorization failures, disconnect during import, expired sessions, duplicate callbacks, and attempted access after deletion. These cases are more informative than checking only the happy path.

Assign an owner to each control and recovery procedure. The wearable integration guide and documentation checklist can organize the surrounding implementation work. A dependable consent design lets users understand their connection, change their choices, and see those choices reflected in ongoing system behavior.