🚧 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, Passport 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 + upload to Passport Prime + launch
See the CLI Reference for every flag.
Signing
Every app on Passport 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)
Passport 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 Passport Prime
🚧 Coming soon. The flow for installing a developer's public key / X.509 certificate onto Passport 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
- API Reference , full rustdoc for the generated KeyOS API crates
- KeyOS, Permissions , the security model behind the manifest