Skip to content

Uniffi poc#49

Merged
abergs merged 23 commits intomainfrom
uniffi-sdk
Apr 15, 2026
Merged

Uniffi poc#49
abergs merged 23 commits intomainfrom
uniffi-sdk

Conversation

@abergs
Copy link
Copy Markdown
Member

@abergs abergs commented Mar 14, 2026

🎟️ Tracking

📔 Objective

This PR adds a initial spaghetti on the wall uniffi bridge for language like:

  • Python, verified (generated bw_remote_uniffi.py)
  • Kotlin, generated .kt bindings
  • Swift, generated .swift + FFI header + modulemap)
  • Ruby, supported by UniFFI 0.28 out of the box
  • C#, so so community-supported via uniffi-bindgen-cs (separate bindgen, not built into uniffi 0.28 core)

📸 Screenshots

⏰ Reminders before review

  • Contributor guidelines followed
  • All formatters and local linters executed and passed
  • Written new unit and / or integration tests where applicable
  • Protected functional changes with optionality (feature flags)
  • Used internationalization (i18n) for all UI strings
  • CI builds passed
  • Communicated to DevOps any deployment requirements
  • Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team

🦮 Reviewer guidelines

  • 👍 (:+1:) or similar for great changes
  • 📝 (:memo:) or ℹ️ (:information_source:) for notes or general info
  • ❓ (:question:) for questions
  • 🤔 (:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion
  • 🎨 (:art:) for suggestions / improvements
  • ❌ (:x:) or ⚠️ (:warning:) for more significant problems or concerns needing attention
  • 🌱 (:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt
  • ⛏ (:pick:) for minor or nitpick changes

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 14, 2026

Logo
Checkmarx One – Scan Summary & Details480b9e55-43a0-4f1c-a4d3-a6c8e6eaedaa


New Issues (1) Checkmarx found the following issues in this Pull Request
# Severity Issue Source File / Package Checkmarx Insight
1 MEDIUM CVE-2026-33532 Npm-yaml-2.8.2
detailsRecommended version: 2.8.3
Description: yaml is a YAML parser and serialiser for JavaScript. Parsing a YAML document with a version of yaml on the 1.x branch prior to 1.10.3 or on the 2.x...
Attack Vector: NETWORK
Attack Complexity: LOW
Vulnerable Package

@sonarqubecloud
Copy link
Copy Markdown

abergs and others added 4 commits April 9, 2026 11:20
Introduces crates/bw-remote-uniffi, a UniFFI-based wrapper around the
Rust protocol stack that generates bindings for Python, Kotlin, Swift,
Ruby, and C# from a single crate using proc-macros (no UDL files).

API surface:
- RemoteAccessClient object (construct, connect, request_credential,
  list_sessions, is_ready, close)
- RemoteCredentialData and SessionInfo records
- RemoteAccessError enum (6 FFI-friendly categories mapped from 18+
  internal error variants)
- connect_and_request top-level convenience function

Includes uniffi-bindgen binary for generating language bindings,
Python example in examples/uniffi/, and full test coverage (21 unit
tests + 5 integration tests with real proxy server).
- Return error on mutex poison in connect() instead of silently dropping
  the connected client
- Increase event channel buffer from 32 to 256 to prevent potential
  deadlock (events are not consumed in headless mode)
- Remove unused event_rx field from RemoteAccessClient
- Implement Drop to auto-close connection if caller forgets close()
- Add double-connect integration test verifying second connect replaces
  the first cleanly
- README.md with setup instructions, usage examples, and multi-language
  binding generation commands
- test.py interactive script with CLI args (--token, --domain, --identity)
- .gitignore to exclude generated bindings and native library artifacts
abergs added 16 commits April 9, 2026 17:13
Split monolithic connect(token, session) into individual pairing methods
mirroring the WASM wrapper pattern. Add UserAccessClient with callback
interfaces for credential serving and event notifications.

RemoteAccessClient API:
- connect() — proxy auth only
- pair_with_handshake(code) — rendezvous pairing
- pair_with_psk(psk_token) — PSK pairing via PskToken::parse()
- load_existing_connection(fingerprint_hex) — cached session
- request_credential(domain) — fetch credential

UserAccessClient API (new):
- CredentialProvider callback interface for handling requests
- EventHandler callback interface for notifications
- get_psk_token() / get_rendezvous_token() for pairing setup

Standalone functions:
- looks_like_psk_token() — token format detection
- list_connections() / clear_connections() — session cache management

Removed: connect_and_request(), is_ready(), manual token parsing,
session auto-selection logic.
- Extract init_tracing() helper (was duplicated in both constructors)
- Add From<ConnectionInfo> for FfiConnectionInfo (was duplicated in 2 places)
- Add From<FfiCredentialData> for CredentialData (replaces ffi_credential_to_internal)
- Fix CredentialRequestSent debug format leak (was using Rust Debug repr)
- Log spawn_blocking panics in callback handlers instead of silently swallowing
- Replace std::mem::forget with Box::leak in test
…allbacks

Rename the UniFFI crate from bw-remote-uniffi to ap-uniffi to match the
ap- prefix convention used by all other workspace crates.

Remove the built-in FileIdentityStorage and FileSessionCache (which
duplicated ap-cli's storage) and replace with callback interfaces
(IdentityStorage, ConnectionStorage) so each language binding provides
its own storage implementation. Add thin adapter structs to bridge
the FFI callbacks to ap_client traits.
- Remove unused serde, serde_json, hex dependencies from ap-uniffi
- Use into_iter() instead of iter() in adapter list() to avoid
  intermediate allocation
- Simplify Python examples to use in-memory storage
- Extract shared storage.py module to deduplicate Python examples
Swift Package Manager project at examples/swift/ demonstrating
RemoteAccessClient usage with in-memory storage implementations.
Includes generated Swift bindings and C FFI header.
- Add bounds check before accessing arg values to prevent index
  out-of-bounds crash when a flag is the last argument
- Gitignore generated ap_uniffi.swift and ap_uniffiFFI.h (matching
  the Python example pattern of not committing generated code)
- Default proxy to wss://ap.lesspassword.dev in Swift and Python examples
- Remove backslash line continuations from README commands (breaks
  when copy-pasting in zsh)
Replace per-object tokio runtimes with a shared lazy runtime and mark
IO methods as async using #[uniffi::export(async_runtime = "tokio")].
This generates native async/await in Swift and suspend in Kotlin,
avoiding blocking the caller's thread.

Callback interfaces (CredentialProvider, EventHandler, IdentityStorage,
ConnectionStorage) remain synchronous as UniFFI requires.
Split verify_fingerprint out of CredentialProvider into a dedicated
FingerprintVerifier callback interface, matching how ap-client treats
these as distinct request types. FingerprintVerifier is optional on
UserAccessClient — when absent, rendezvous fingerprints are auto-accepted.
Fingerprint verification only applies to rendezvous pairing, so passing
it at construction time is broader than needed. Leave a note to revisit.
RemoteAccessClient → RemoteClient, UserAccessClient → UserClient,
RemoteAccessError → ClientError. Uses fully qualified paths
(ap_client::RemoteClient, etc.) to disambiguate from the wrapped types.
Rename matches the existing user_client.rs convention.
@abergs abergs marked this pull request as ready for review April 14, 2026 11:16
abergs added 3 commits April 14, 2026 13:29
Replace .ok() calls in stored_to_info and info_to_stored with explicit
match arms that log warnings when fingerprint parsing or transport state
serialization fails. Also document spawned task lifecycle on forwarders.
- Replace std::sync::Mutex with tokio::sync::Mutex in both clients
- Add FfiCredentialQuery enum (Domain/Id/Search) replacing string-typed query
- Expose full credential query types and configurable timeout on request_credential
- Add get_identity_fingerprint() to both RemoteClient and UserClient
- Add connection_name parameter to get_psk_token and get_rendezvous_token
- Add FingerprintVerifier support on RemoteClient for rendezvous verification
- Add AuditLogger callback interface with FfiAuditEvent enum
- Add PskStorage callback interface with FfiPskEntry for persistent PSK storage
- Update CredentialProvider callback to use FfiCredentialQuery enum
- Update examples and integration tests for new API signatures
…num, fix verifier API

- Extract resolve_identity_fingerprint() to eliminate duplication across both clients
- Replace connection_type: String with FfiConnectionType enum in FfiAuditEvent
- Change FingerprintVerifier.verify_fingerprint remote_identity to Option<String>
  so RemoteClient passes None instead of misleading empty string
- Remove redundant comments
@abergs abergs merged commit 3a53b07 into main Apr 15, 2026
12 of 13 checks passed
@abergs abergs deleted the uniffi-sdk branch April 15, 2026 09:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant