Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,23 @@ This skill explains SmartThings device onboarding QR requirements across Matter,
- Developers validating QR payload fields before publication
- Partners handling Matter, Zigbee 3.0, Direct Connected, or Mobile Connected onboarding flows

### 5. App-to-App Account Linking

> **Skill**: `smartthings-app-to-app-linking-developer`

This skill guides mobile app developers in implementing seamless App-to-App Account Linking between native Android/iOS applications and the SmartThings app, specifically for Cloud Connected (ST-Schema) integrations.

**Key features**
- Associated Domains and Digital Asset Links (`assetlinks.json` / AASA) validation and configurations
- Native Android Manifest intent filters and Kotlin code templates for intent parsing and callback assembly
- Xcode capabilities and Swift UserActivity delegate handling for iOS callback routing
- Support instructions for new vs. already certified Schema Apps
- Developer Mode setup and end-to-end device testing workflows

**Best fit**
- Mobile application developers building native smart home apps for Android and iOS
- Teams integrating ST-Schema apps looking to enable App-to-App account linking

---

## ⚠️ Limitations and Notes
Expand Down
79 changes: 79 additions & 0 deletions skills/smartthings-app-to-app-linking-developer/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
name: smartthings-app-to-app-linking-developer
description: Guides developers through setting up and implementing SmartThings App-to-App Account Linking for Android and iOS mobile devices, specifically for Cloud Connected (ST-Schema) integrations. Enforces dynamic lookup of the official documentation as the source of truth.
metadata:
version: "2026-06-09"
---

# SmartThings App-to-App Account Linking Guide

This skill helps developers implement seamless App-to-App Account Linking between their native mobile applications (Android/iOS) and the SmartThings app.

> [!IMPORTANT]
> - App-to-App Account Linking is supported exclusively for **Cloud Connected (ST-Schema)** integrations.
> - **Source of Truth Rule**: The AI agent **MUST** fetch and read the live content of `https://developer.smartthings.com/docs/devices/cloud-connected/app-to-app-linking` at the beginning of the task to retrieve the absolute source-of-truth code blocks, intent parsing logic, and regional redirect URIs.

## Core Operating Principles

1. **Source of Truth Dynamic Lookup**: Always fetch `https://developer.smartthings.com/docs/devices/cloud-connected/app-to-app-linking` to read the official Kotlin/Swift code implementations, query parameter names, and callback domains. Do not output stale code or static assumptions; instead, inspect the official documentation dynamically during execution.
2. **Language Adaptation**: Respond in the developer's language of choice (e.g., Korean, English) and reuse existing context.
3. **Phase-by-Phase Progression**: App-to-App linking requires both environment configuration and code changes. Progress step-by-step with the user, ensuring domain configurations are set before code is written.
4. **Dynamic Callback Enforcement**: Always instruct the developer to parse parameters (`client_id`, `state`, `redirect_uri`, `response_type`) from incoming intents dynamically. Do not allow hardcoding of callback URLs, as SmartThings hosts regional domains. When returning the authorization code, the query parameter key must be strictly fixed to `code`.
5. **Certified/Published App Rule**: If the Schema App is already certified/published, the developer must contact SmartThings support/WWST team to apply the App-Link/Universal Link rather than modifying it directly.
6. **Merge Digital Asset Files**: When generating `assetlinks.json` or `apple-app-site-association`, do not overwrite existing files. Read the existing file first, parse its JSON, and append/merge the new SmartThings association block to preserve other integrations (e.g., Google/Apple login or other deep links).
7. **User Consent & Disclosure Enforcement & Checklists**: Focus on guiding the implementation using detailed checklists (Android/iOS Phase 2 & 3 guidelines) rather than copy-pasting local code templates. Before issuing an authorization code, the partner app **MUST** display a clear consent screen explaining that the user's devices will be linked to and controllable by the SmartThings app. Explicit user action is required, and the cancel path must map to `error=unauthorized`.
8. **Vibe Coding Compliance & Spec Adherence**: When generating or writing integration codes dynamically (often termed "Vibe Coding" or AI code generation), the AI assistant and developer must strictly adhere to the technical specifications defined in the Phase 2 & 3 checklists. Do not omit critical security and integration details (such as `client_id` validation, `state` parameter consistency, returning the authorization code strictly via the `code` query parameter key, and `universalLinksOnly` options) for the sake of simplified code output. Every checkpoint in the reference checklists must be rigorously met to prevent runtime failures and comply with WWST certification standards.

## Persona and Goals
This skill supports:
- Native mobile developers (Kotlin, Swift) integrating their smart home application with the SmartThings ecosystem.
- Developers looking to improve user onboarding completion rates by avoiding browser-based OAuth flows.

> [!IMPORTANT]
> **UX Responsibility**: App-to-App Account Linking transfers authority over the user's physical devices to SmartThings. The partner app is responsible for presenting a proper consent UI to the user before completing the OAuth flow. The AI assistant must remind developers of this UX obligation at the implementation phase.

## Specialized Debugging Summary (Quick Reference)

| Symptom | Cause | Resolution |
| :--- | :--- | :--- |
| SmartThings app falls back to browser OAuth | Native app not installed, or OS verification of App Links/Universal Links failed. | Check `assetlinks.json` or `apple-app-site-association` hosting and format. |
| Account linking completes but state is missing | Partner app did not return the exact `state` token received from SmartThings. | Ensure incoming `state` param is saved and appended to callback. |
| Redirect back to SmartThings fails | Invalid or hardcoded callback URL. | Decode the incoming `redirect_uri` param dynamically using UTF-8. |

## Code Writing Reference (Deep Link Parameters)

Refer to the official documentation for parsing logic. Expect these query parameters from the incoming link:
* `client_id` (String): Validate this against your known Client ID for security.
* `response_type` (String): Fixed to `code`. The parameter key name you must use when returning your authorization code is strictly fixed to `code`.
* `state` (String): Session identifier. Must be passed back exactly as-is.
* `redirect_uri` (String): Encoded SmartThings callback URL. Decode using UTF-8 before appending parameters.

## Overall Process (App-to-App Linking Sequence)

### Phase 1: Environment Setup and Domain Verification
Establish secure association between your app domain and the mobile app binary.
**➔ Read `references/01-environment-setup.md` to guide the user.**

### Phase 2: Android App Links Implementation
Configure your Android app Manifest, register intent filters, parse incoming params, and trigger login.
**➔ Read `references/02-android-implementation.md` to write/guide the code.**

### Phase 3: iOS Universal Links Implementation
Configure iOS Associated Domains, handle user activities in Swift, and redirect back.
**➔ Read `references/03-ios-implementation.md` to write/guide the code.**

### Phase 4: SmartThings Console Registration & Testing
After code implementation, the developer **must** register the App-to-App Link URLs in the SmartThings Developer Console **before** any device testing.

**Console navigation path**:
[SmartThings Developer Console](https://developer.smartthings.com/console) → **Device Integrations** → **Schema Apps** tab → Select your Schema App → **App-to-App Linking (optional)** section

> The AI assistant **must walk the developer through this console step** after Phase 2/3 code implementation is complete, and **before** instructing them to run device tests. Do not skip directly to testing.

**➔ Read `references/04-registration-and-testing.md` to guide the user.**

---

## Key Reference Links (Global References)

* Official App-to-App Linking Guide: `https://developer.smartthings.com/docs/devices/cloud-connected/app-to-app-linking` (Source of Truth)
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Phase 1: Environment Setup

Establish secure domain-to-app associations for Android App Links and iOS Universal Links.

---

## 💡 Concept Overview: App Links & Universal Links

> [!IMPORTANT]
> **Key Integration Rules**:
> * **ST-Schema Only**: App-to-App Account Linking is supported **exclusively** for Cloud Connected (ST-Schema) integrations.
> * **Browser Fallback**: If the partner application is not installed on the user's mobile device, the SmartThings App automatically falls back to standard web browser-based OAuth.

* **Definition**: OS-level features (Android App Links / iOS Universal Links) that open your native app directly when a web URL (HTTP/HTTPS) is clicked, skipping browser selection popups.
* **Why use them instead of custom URI schemes (e.g., `myapp://`)?**:
1. **Security**: The OS verifies domain ownership via `assetlinks.json`/AASA to prevent malicious apps from hijacking your links.
2. **Smooth Fallback**: If the app is not installed, the OS cleanly opens the website in Safari/Chrome instead of failing.

### Account Linking Flows

The diagram below outlines the overall OAuth authorization and token exchange process, highlighting the secure App-to-App flow (shaded in blue) and the traditional App-to-Web fallback:

```mermaid
sequenceDiagram
autonumber
participant ST as SmartThings
participant STApp as SmartThings App
participant YourApp as Your App
participant YourAuth as Your Auth Server
participant YourConnector as Schema App

alt App to App case
rect rgb(204, 242, 255)
STApp->>YourApp: Launch your app to get an authorization code
Note over YourApp: Agree user consent
YourApp->>YourAuth: Request an authorization code in secure path
YourAuth-->>YourApp: Authorization code
YourApp-->>STApp: Authorization code
end
else App to Web case
STApp->>YourAuth: Request authorization code (via Webview)
Note over YourAuth: Sign in / Agree user consent
YourAuth-->>STApp: Authorization code
end

STApp->>ST: Redirect authorization code
ST->>YourAuth: Request access token (using auth code)
YourAuth-->>ST: Access token
ST->>YourConnector: Interactions such as discovery with access token
```

---

> [!IMPORTANT]
> **Domain Ownership `{your-domain}`**:
> All occurrences of `{your-domain}` (or `yourdomain.com`) in the paths and console registration parameters refer to the developer's **own verified server domain** (e.g., `yourcompany.com`).
> * **Ownership**: Must be fully owned and controlled by your organization.
> * **Security**: Must support SSL/TLS over HTTPS (HTTP is not permitted by mobile operating systems).
> * **Consistency**: The domain and path prefix must match exactly across the console settings, mobile source codes, and hosted digital asset files.

## 🤖 Android App Links Setup

* **File Target**: `https://{your-domain}/.well-known/assetlinks.json`
* **Requirements**: Serve over HTTPS, response Content-Type `application/json`, HTTP `200 OK` status, and no redirects.
* **Source of Truth**: Refer to the **Account Linking on Android > Prerequisites** section of the [Official App-to-App Documentation](https://developer.smartthings.com/docs/devices/cloud-connected/app-to-app-linking#prerequisites) for the verified JSON payload structure, Play Console signing key details, and relation attributes.

---

## 🍏 iOS Universal Links Setup

* **File Target**: `https://{your-domain}/.well-known/apple-app-site-association` (no extension)
* **Requirements**: Serve over HTTPS, response Content-Type `application/json`, HTTP `200 OK` status, and no redirects.
* **Source of Truth**: Refer to the **Account Linking on iOS > Prerequisites** section of the [Official App-to-App Documentation](https://developer.smartthings.com/docs/devices/cloud-connected/app-to-app-linking#prerequisites-1) to retrieve the required `apple-app-site-association` JSON schema, App ID formatting (`TeamID.BundleID`), and components mapping.

---

## 🔑 Preparation Checklist (Domain Files & Console)

| OS | Parameter | Purpose / Target Destination |
| :--- | :--- | :--- |
| **Android** | Package Name | Defined in `assetlinks.json` on your server (`applicationId` in `build.gradle`) |
| | SHA-256 Fingerprint | Defined in `assetlinks.json` on your server (from app signing key) |
| | Android App-to-App Link | Entered in SmartThings Console (e.g., `https://yourdomain.com/smartthings-auth`) |
| **iOS** | Bundle ID | Defined in `apple-app-site-association` (AASA) on your server |
| | Team ID | Defined in `apple-app-site-association` (AASA) on your server (10-char Apple Team ID) |
| | iOS App-to-App Link | Entered in SmartThings Console (e.g., `https://yourdomain.com/smartthings-auth`) |
| | App Store ID | (Optional) Entered in SmartThings Console for App Store redirection |

---

## 🛠️ File Generation Support

The AI assistant can automatically generate domain association files directly in your workspace. Provide the following parameters to request generation:
* **Android (`assetlinks.json`)**: Package Name & SHA-256 fingerprint.
* **iOS (`apple-app-site-association`)**: App Bundle ID & Apple Developer Team ID.

> [!IMPORTANT]
> **Preserving Existing Domain Associations (Merge Rule)**:
> If you already have existing domain verification files, the AI assistant must **not** overwrite them. It will read the existing JSON contents and **merge** the new SmartThings credentials into the existing arrays/dictionaries, ensuring that existing configurations (e.g. Google Login, Apple Sign In, or other custom App Links) remain functional.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Phase 2: Android Coding Checkpoints

When implementing Android App Links for SmartThings App-to-App Linking, the AI assistant must implement and verify the following checkpoints:

---

## 🔑 Coding Checkpoints

* **[ ] Manifest Intent-Filter URL Matching**:
Configure the `<intent-filter>` in `AndroidManifest.xml` with `android:autoVerify="true"` for the authentication Activity. The `<data>` element must define the exact `scheme` (`https`), `host` (your domain), and `pathPrefix` (e.g., `/smartthings-auth`) that matches the **Android App-to-App Link** registered in the SmartThings Developer Console.
* **[ ] Intent Query Parameter Parsing**:
Extract the incoming deep link URL from the intent using `intent.data` or `intent.dataString`. Parse this URL (e.g., via `Uri.parse()`) and dynamically retrieve the standard OAuth parameters:
- `client_id`: The client ID of your integration.
- `redirect_uri`: The target callback URL hosted by SmartThings.
- `response_type`: Expected token key (usually `code`).
- `state`: Verification token to prevent CSRF.
Use standard Android `Uri` query parser methods (e.g., `getQueryParameter("key")`) to extract these values.
* **[ ] Client ID Security Check**:
Validate the incoming `client_id` parameter against the expected Integration Client ID. If they mismatch, terminate the authentication immediately to prevent link hijacking.
* **[ ] User Consent & Disclosure Screen** ⚠️:
Before presenting the login screen or issuing any authorization code, **display a clear consent screen** informing the user that:
- Their account will be linked to the SmartThings app.
- SmartThings will be able to discover and control their registered devices.
- They can revoke this access at any time via their account settings.

The consent screen must require an **explicit user action** (e.g., tapping "Agree" / "Authorize" button). If the user declines or cancels, trigger the **failure callback** (`error=unauthorized`).
* **[ ] Dynamic Callback Assembly & UTF-8 Handling**:
Do not hardcode the SmartThings callback URL. Extract the `redirect_uri` query parameter from the incoming deep link. Because the Android `Uri` parser automatically URL-decodes query values, parse the extracted `redirect_uri` string to construct the final callback target domain and path.
* **[ ] Fixed Callback Query Key ('code')**:
Append the authorization code to the success callback strictly using the `code` query parameter key (e.g., `?code=AUTH_CODE`). Do not dynamically map other key names based on `response_type`.
* **[ ] State Parameter Match**:
Retrieve the exact `state` token received from the incoming intent, and return it exactly as-is under the query parameter key `state` in the callback URL.
* **[ ] Failure Handoff Handling**:
If authentication fails, is rejected, or is cancelled, build the redirect callback URL by appending the `error` query parameter with a descriptive error string (e.g., `error=unauthorized`) and the exact `state` received, and redirect back to SmartThings.
* **[ ] Native Redirection via ACTION_VIEW**:
To hand control back to the SmartThings app, construct the callback URL (e.g., `https://c2c-us.smartthings.com/c2c-app-to-app-account-linking?state=...&code=...` or with `error=unauthorized`) and launch it using a native Intent with `Intent.ACTION_VIEW`. Do not load this URL in a WebView.

---


## 💻 CLI Verification (Testing your App Link)

To test if your Android app is configured correctly to receive the App Link without needing the SmartThings app, run the following ADB command in your terminal:

```bash
adb shell am start -W -a android.intent.action.VIEW \
-d "https://{your-domain}/smartthings-auth?client_id={your-client-id}&response_type=code&state=xyz123&redirect_uri=https%3A%2F%2Foauth.smartthings.com" \
{your-package-name}
```

*Replace `{your-domain}`, `{your-client-id}`, and `{your-package-name}` with your actual parameters. If the setup is correct, this command will launch your authentication Activity directly on the connected device.*


Loading
Loading