🚧 The Passport Prime SDK is in public beta. Got an idea, or want a dev unit to play with? We'd love to hear from you — hello@foundation.xyz .
What is an app on KeyOS?
An app is a Rust binary crate that runs as an isolated process under the Xous microkernel. Each app gets its own address space, its own storage scope, and its own declared permissions — all enforced by the kernel. There is no runtime escalation path.
Apps compile to the armv7a-unknown-xous-elf target, are signed with cosign2, and are installed under apps/<app-name>/ on the device.
Project layout
my-app/
├── app-config.toml # app identity, publisher, permissions, signing
├── Cargo.toml
├── build.rs # Slint code generation (router, exports, i18n)
├── src/
│ └── main.rs # entry point
├── ui/
│ ├── app.slint # top-level UI component
│ └── pages/ # per-page components (multi-page-app template)
├── resources/
│ └── icon.svg # launcher icon
└── i18n/
└── en.json # translation strings
foundation new my-app scaffolds this layout for you. Two templates ship with the SDK:
default-app— single-page startermulti-page-app— router-based multi-screen starter
app-config.toml
This is the source of truth for your app's identity, publisher metadata, required permissions, and signing configuration. Every field maps one-to-one onto an internal AppConfig struct — no hidden defaults.
app-name = "my-app"
friendly-app-name = "My App"
launcher-app-name = "My App"
description = "Example application"
icon = "resources/icon.svg"
app-id = "0x00112233445566778899aabbccddeeff"
version = "0.1.0"
min-keyos-version = "1.0.0"
signing-identity = "Example Company"
cosign2-config = "~/.foundation/signing/my-app/cosign2.toml"
[publisher]
name = "Example Company"
contact-email = "support@example.com"
support-url = "https://example.com/support"
[permissions]
"os/settings" = ["GetDeviceName"]
Field reference
| Field | Required | Notes |
|---|---|---|
app-name | ✅ | Cargo package name and build output directory name |
friendly-app-name | ✅ | Display name |
launcher-app-name | — | Falls back to friendly-app-name |
description | ✅ | One-line description |
icon | ✅ | Path relative to the project root; validated at build time |
app-id | ✅ | 0x-prefixed even-length hex; must be unique on the device |
version | ✅ | Semver |
min-keyos-version | ✅ | Minimum KeyOS version your app requires |
signing-identity | — | Selects an identity under ~/.foundation/signing/<name>/ |
cosign2-config | — | Explicit path to a cosign2.toml; overrides identity resolution |
[publisher] | ✅ | name, contact-email, support-url |
[permissions] | ✅ | Per-service entries: "os/<service>" = ["MethodA", "MethodB"] |
The UI: Slint with a curated component library
KeyOS apps use Slint
for UI. The SDK exposes a stable @ui/... import surface — a curated library of Foundation-designed components, theme tokens, fonts, and icons. Your app imports from @ui and inherits a polished, on-brand starting point that you're free to fully restyle.
A minimal ui/app.slint:
import { BaseWindow } from "@ui/widgets.slint";
import { Button } from "@ui/widgets.slint";
export component AppWindow inherits BaseWindow {
Button {
text: "Hello, Prime";
clicked => { debug("button pressed"); }
}
}
Components available from @ui/...:
- Form controls —
Input,Checkbox,RadioButton,Slider,Dropdown,Switch,Pagination,SegmentedSelector - Navigation —
Drawer,Dialog,ModalWindow,PopupMenu - Display —
Card,Chip,Badge,Button,IconButton,Progress, QR code renderer - Specialized —
AuthWidget,CryptoFiatField,SeedWords,PinEntry,SlideToButton,FileList - Theming —
ColorPicker,CircularProgress,Shimmer, full design tokens
Live-preview any .slint file with foundation preview ui/app.slint.
A minimal src/main.rs
The app! macro from slint_keyos_platform wires your top-level AppWindow into the KeyOS runtime:
// SPDX-License-Identifier: Apache-2.0
use slint_keyos_platform::app;
app!("My App");
fn app_main(_cx: AppContext, ui: AppWindow) {
log_server::init_wait(env!("CARGO_CRATE_NAME")).unwrap();
log::set_max_level(log::LevelFilter::Info);
log::info!("My App starting");
// The Slint event loop runs automatically inside app!()
// Wire up UI callbacks, spawn tasks, subscribe to IPC events here.
}
Build, simulate, preview
From inside an SDK shell (foundation develop):
foundation new my-app # scaffold from template
cd my-app
foundation sim # hosted simulator (debug)
foundation preview ui/app.slint # live Slint preview
foundation build # release-quality signed hardware build
foundation sideload # build + copy to Prime + launch
See the CLI Reference for every flag.
Signing
Every app on Prime is signed. foundation build signs app.elf in place with cosign2 using a secp256k1 key.
One-time identity setup:
foundation cert gen "My Company"
This writes four files to ~/.foundation/signing/My Company/:
private.pem— secp256k1 private key (keep secret)public.pub— compressed public key hexcertificate.crt— self-signed X.509 code-signing certificatecosign2.toml— the configfoundation buildconsumes
Identity resolution order at build time:
cosign2-configinapp-config.toml(explicit path)signing-identityinapp-config.toml(name under~/.foundation/signing/)- An identity whose name matches
[publisher].name - The only configured identity, if exactly one exists
- Interactive prompt (errors in non-interactive contexts)
Prime's app launcher verifies the signature against the embedded certificate chain before starting your app. Tampered or unsigned binaries are refused.
Registering your developer certificate on Prime
🚧 Coming soon. The flow for installing a developer's public key / X.509 certificate onto Prime (so sideloaded apps built under your identity are trusted) is still being designed. Expected to live under the Apps section in Settings. Watch this space — or email hello@foundation.xyz if you're an early-access partner and need the current interim flow.
Toolchain
| Component | Detail |
|---|---|
| Rust toolchain | Nightly, pinned by the SDK |
| Target triple | armv7a-unknown-xous-elf |
| Build flags | RUSTFLAGS="--cfg keyos -C relocation-model=pic -C link-arg=-pie" for hardware, --cfg keyos for simulator |
| Signing | cosign2 (secp256k1 + X.509) |
| Build orchestration | cargo + foundation CLI (cargo xtask for SDK maintainers) |
| Environment | Nix flake (foundation develop enters it) |
You don't install Rust or manage the cross-compiler manually — foundation develop hands you a shell with everything already in place.
Next
- CLI Reference — full command and flag reference
- Capabilities — services your app can declare and call
- KeyOS — Permissions — the security model behind the manifest