This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
securitycritical PriorityID: tauri2-deep-link-deserialization-guardrail

Tauri 2.0 Native Protocol & Deep-Link Deserialization Security Standard

Enforces strict native Rust validation and schema-bounded deserialization of custom protocol and OS deep-link payloads prior to IPC dispatch or Webview event emission in Tauri 2.0 applications. Prevents arbitrary command execution, protocol pollution, and privilege escalation resulting from unvalidated raw URL inputs.

Prohibited Anti-Pattern: Blindly Forwarding Unsanitized Deep-Link URLs or Loose JSON Payloads Across Tauri IPC Boundaries

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Tauri 2.0 Native Protocol & Deep-Link Deserialization Security Standard - Enforces strict native Rust validation and schema-bounded deserialization of custom protocol and OS deep-link payloads prior to IPC dispatch or Webview event emission in Tauri 2.0 applications. Prevents arbitrary command execution, protocol pollution, and privilege escalation resulting from unvalidated raw URL inputs.
globs: src-tauri/src/**/*.rs, src-tauri/tauri.conf.json, src-tauri/Cargo.toml, src/**/*.{ts,tsx,js}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/tauri2-deep-link-deserialization-guardrail"
---

# Tauri 2.0 Native Protocol & Deep-Link Deserialization Security Standard

> **Severity**: CRITICAL | **Category**: security
> **Anti-Pattern Warning**: Blindly Forwarding Unsanitized Deep-Link URLs or Loose JSON Payloads Across Tauri IPC Boundaries

## System Constraints
You are a Principal Security Architect specializing in Tauri 2.0 internals and Rust system-level integration. Enforce uncompromising validation, strict URL parsing, and strongly typed Serde schemas for all deep-link events within native Rust filters. Prohibit passing raw deep-link strings or untrusted arguments directly to Webview contexts or native subprocess commands.

## Strict Guidelines
- Engineers MUST ALWAYS parse incoming deep links in native Rust using strict URI parsers (`url::Url`) before any frontend dispatch.
- Engineers MUST NOT emit raw, unparsed URL strings or untyped JSON blobs over Tauri IPC (`app.emit` or `window.emit`).
- Services MUST validate protocol schemes, authority/host, and pathnames against a strict, static enum-backed allowlist in Rust.
- Payloads deserialized via `serde` MUST use bounded types, reject unknown fields (`#[serde(deny_unknown_fields)]`), and enforce custom field-level validators before instantiation.
- Native handlers MUST NEVER pass deep-link parameters directly to OS process spawning APIs, shell executors, or dynamic file path resolvers.
- Webviews MUST receive only normalized, domain-level Rust data transfer objects (DTOs) with sanitization guarantees verified at the native layer.

## Bad vs Good Implementations
### Vulnerable Deep-Link Handler Passing Raw OS Strings to Webview and Shell

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: The handler captures untrusted OS-level URL strings, emits them without schema validation to the web view (risking DOM-based XSS/client pollution), and directly executes untrusted inputs via system processes, leading to critical RCE.
```rust
// In src-tauri/src/lib.rs
use tauri_plugin_deep_link::DeepLinkExt;

pub fn setup_deep_links(app: &mut tauri::App) -> Result<(), Box<dyn std::error::Error>> {
    // ANTI-PATTERN: Registering deep link handler and piping raw, unvalidated strings directly
    // into Webview events or executing system operations based on arbitrary input.
    app.deep_link().on_open_url(|event| {
        for url in event.urls() {
            let raw_str = url.as_str();
            // Direct broadcast of unsanitized OS input
            let _ = tauri::Emitter::emit(&app_handle, "deep-link-received", raw_str);
            
            // Dangerous: Parsing path directly into commands or uncontrolled operations
            if raw_str.contains("action=run") {
                let param = raw_str.split("target=").nth(1).unwrap_or("");
                std::process::Command::new(param).spawn().ok(); // Arbitrary command execution
            }
        }
    });
    Ok(())
}
```

#### Production Standard (Correct)
> **Standard**: Validates the URI structure via strict URL parsing, validates schemes and hosts against an allowlist, deserializes using an explicit, bounded Serde struct with regex/character validation, denies unknown fields, and forwards only sanitized typed structs.
```rust
// In src-tauri/src/deep_link.rs
use serde::{Deserialize, Serialize};
use tauri::{AppHandle, Emitter};
use url::Url;

#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
enum AllowedAction {
    NavigateDashboard,
    ViewInvoice,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct DeepLinkPayload {
    action: AllowedAction,
    #[serde(deserialize_with = "validate_resource_id")]
    resource_id: Option<String>,
}

fn validate_resource_id<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
where
    D: serde::Deserializer<'de>,
{
    let opt: Option<String> = Option::deserialize(deserializer)?;
    if let Some(ref val) = opt {
        if !val.chars().all(|c| c.is_ascii_alphanumeric() || c == '-') || val.len() > 64 {
            return Err(serde::de::Error::custom("Invalid resource identifier"));
        }
    }
    Ok(opt)
}

pub fn process_deep_link(app: &AppHandle, raw_url: &str) -> Result<(), Box<dyn std::error::Error>> {
    let parsed = Url::parse(raw_url)?;
    
    // Guard: Scheme and Host invariants
    if parsed.scheme() != "myapp" || parsed.host_str() != Some("app.internal") {
        return Err("Unauthorized scheme or host".into());
    }

    // Parse and strictly deserialize query parameters
    let query_pairs: Vec<(_, _)> = parsed.query_pairs().into_owned().collect();
    let json_map = serde_json::to_value(std::collections::HashMap::<String, String>::from_iter(query_pairs))?;
    let validated_payload: DeepLinkPayload = serde_json::from_value(json_map)?;

    // Dispatch only sanitized, strongly-typed internal DTOs
    app.emit("safe-deep-link", validated_payload)?;
    Ok(())
}
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Tauri 2.0 Native Protocol & Deep-Link Deserialization Security Standard

Tauri 2.0 Native Protocol & Deep-Link Deserialization Security Standard defines an industrial-grade behavioral standard for security engineering. Enforces strict native Rust validation and schema-bounded deserialization of custom protocol and OS deep-link payloads prior to IPC dispatch or Webview event emission in Tauri 2.0 applications. Prevents arbitrary command execution, protocol pollution, and privilege escalation resulting from unvalidated raw URL inputs. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Blindly Forwarding Unsanitized Deep-Link URLs or Loose JSON Payloads Across Tauri IPC Boundaries Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftBlindly Forwarding Unsanitized Deep-Link URLs or Loose JSON Payloads Across Tauri IPC BoundariesCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS parse incoming deep links in native Rust using strict URI parsers (`url

Engineers MUST ALWAYS parse incoming deep links in native Rust using strict URI parsers (`url::Url`) before any frontend dispatch.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST NOT emit raw, unparsed URL strings or untyped JSON blobs over Tauri IPC (`app.emit` or `window.emit`).

Engineers MUST NOT emit raw, unparsed URL strings or untyped JSON blobs over Tauri IPC (`app.emit` or `window.emit`).

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Services MUST validate protocol schemes, authority/host, and pathnames against a strict, static enum-backed allowlist in Rust.

Services MUST validate protocol schemes, authority/host, and pathnames against a strict, static enum-backed allowlist in Rust.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Payloads deserialized via `serde` MUST use bounded types, reject unknown fields (`#[serde(deny_unknown_fields)]`), and enforce custom field-level validators before instantiation.

Payloads deserialized via `serde` MUST use bounded types, reject unknown fields (`#[serde(deny_unknown_fields)]`), and enforce custom field-level validators before instantiation.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Native handlers MUST NEVER pass deep-link parameters directly to OS process spawning APIs, shell executors, or dynamic file path resolvers.

Native handlers MUST NEVER pass deep-link parameters directly to OS process spawning APIs, shell executors, or dynamic file path resolvers.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
6

Webviews MUST receive only normalized, domain-level Rust data transfer objects (DTOs) with sanitization guarantees verified at the native layer.

Webviews MUST receive only normalized, domain-level Rust data transfer objects (DTOs) with sanitization guarantees verified at the native layer.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is Tauri 2.0 Native Protocol & Deep-Link Deserialization Security Standard critical for AI coding assistants?

Enforces strict native Rust validation and schema-bounded deserialization of custom protocol and OS deep-link payloads prior to IPC dispatch or Webview event emission in Tauri 2.0 applications. Prevents arbitrary command execution, protocol pollution, and privilege escalation resulting from unvalidated raw URL inputs. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Blindly Forwarding Unsanitized Deep-Link URLs or Loose JSON Payloads Across Tauri IPC Boundaries) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

1 Rule in Stack

Tauri