Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
da93824
Add Rust application ABI and SDK foundation
Copilot Aug 23, 2026
fdd861a
Add Rust sample tests and documentation
Copilot Aug 23, 2026
c946e2b
Finalize Rust SDK packaging and validation fixes
Copilot Aug 23, 2026
7a24948
Address Rust SDK review feedback
Copilot Aug 23, 2026
c2a4b41
Separate Rust app SDK from core Rust archive
Copilot Aug 23, 2026
0cd4658
Address final Rust SDK review feedback
Copilot Aug 23, 2026
4e6bf97
Use public KV API in Rust bridge
Copilot Aug 23, 2026
71d8920
Compile Rust bridge with public map type
Copilot Aug 23, 2026
99d8628
Reference Rust exploration PR in changelog
achamayou Aug 24, 2026
8b91d0b
Harden Rust bridge integration
achamayou Aug 26, 2026
30b12d6
Address Rust interface review feedback
achamayou Aug 26, 2026
cb80eac
Merge branch 'main' into achamayou-rust-interface-exploration
achamayou Aug 28, 2026
1019c22
Update 7.0.14 changelog entry and package version
Copilot Aug 29, 2026
04c7fd1
Align EndpointError status validation with HTTP_STATUS_MAP
Copilot Aug 29, 2026
005256d
Add Rust panic endpoint for app-boundary test coverage
Copilot Aug 29, 2026
941258d
Add comment linking is_known_error_status to HTTP_STATUS_MAP
Copilot Aug 29, 2026
7e966d2
Finalize Rust panic-boundary validation and comment fix
Copilot Aug 29, 2026
b4dec96
Potential fix for pull request finding
achamayou Aug 29, 2026
49320aa
Merge origin/main into rust interface exploration
Copilot Sep 1, 2026
2f46f9d
Merge branch 'main' into achamayou-rust-interface-exploration
achamayou Sep 1, 2026
71ab223
Ignore expected Rust panic-hook stderr in basic_rust test
achamayou Sep 2, 2026
5f9b287
Address Rust interface review findings
achamayou Sep 2, 2026
c0cf818
Merge branch 'main' into achamayou-rust-interface-exploration
achamayou Sep 2, 2026
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

[7.0.14]: https://github.com/microsoft/CCF/releases/tag/ccf-7.0.14

### Added

- Native CCF applications can now be written in Rust through a minimal API for registering endpoints and accessing raw-byte KV maps (#8200).

### Changed

- CCF and C++ applications built against it now require C++23. The supported minimum Clang version remains 18.1.2. (#8234)
Expand Down
41 changes: 41 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,27 @@ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/tools.cmake DESTINATION cmake)

include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/ccf_app.cmake)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ccf_app.cmake DESTINATION cmake)
install(
DIRECTORY ${CCF_DIR}/src/rust/
DESTINATION share/ccf/src/rust
PATTERN target EXCLUDE
)
install(
DIRECTORY ${CCF_DIR}/src/cose/cose_rs/
DESTINATION share/ccf/src/cose/cose_rs
PATTERN target EXCLUDE
)
install(
DIRECTORY ${CCF_DIR}/3rdparty/internal/cose-openssl/
DESTINATION share/ccf/3rdparty/internal/cose-openssl
PATTERN target EXCLUDE
)
install(FILES ${CCF_DIR}/src/rust/app_bridge.cpp DESTINATION share/ccf/rust)
install(
FILES ${CCF_DIR}/samples/apps/main.cpp
DESTINATION share/ccf/rust
RENAME app_main.cpp
)

# Copy and install CCF utilities
set(CCF_UTILITIES keygenerator.sh submit_recovery_share.sh)
Expand Down Expand Up @@ -575,6 +596,19 @@ if(BUILD_TESTS)

# Unit tests
if(BUILD_UNIT_TESTS)
add_test(
NAME ccf_app_rust_test
COMMAND
${CMAKE_COMMAND} -E env --unset=CARGO_BUILD_TARGET "CARGO_NET_RETRY=10"
"CARGO_HTTP_TIMEOUT=60" "CARGO_BUILD_RUSTC=${RUSTC}" ${CARGO} test
--manifest-path ${CCF_DIR}/src/rust/ccf-app/Cargo.toml --target-dir
${CMAKE_BINARY_DIR}/cargo/ccf-app-test --locked
)
set_tests_properties(
ccf_app_rust_test
PROPERTIES LABELS unit WORKING_DIRECTORY ${CCF_DIR}/src/rust/ccf-app
)

add_test(
NAME verify_uvm_attestation_and_endorsements
COMMAND
Expand Down Expand Up @@ -1299,6 +1333,13 @@ if(BUILD_TESTS)
ADDITIONAL_ARGS --js-app-bundle ${CMAKE_SOURCE_DIR}/samples/apps/logging/js
)

add_e2e_test(
NAME basic_rust
PYTHON_SCRIPT ${CMAKE_SOURCE_DIR}/tests/basic_rust.py
BUCKET bucket_c
ADDITIONAL_ARGS --package samples/apps/basic_rust/basic_rust
)

set(
RBAC_CONSTITUTION_ARGS
--constitution
Expand Down
83 changes: 83 additions & 0 deletions cmake/ccf_app.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,89 @@ function(add_ccf_app name)
endif()
endfunction()

function(add_ccf_rust_app name)
cmake_parse_arguments(
PARSE_ARGV 1
PARSED_ARGS
""
"MANIFEST_PATH;PACKAGE;LIB_NAME"
""
)

if(NOT PARSED_ARGS_MANIFEST_PATH)
message(FATAL_ERROR "add_ccf_rust_app requires MANIFEST_PATH")
endif()
if(NOT PARSED_ARGS_PACKAGE)
set(PARSED_ARGS_PACKAGE ${name})
endif()
if(NOT PARSED_ARGS_LIB_NAME)
set(PARSED_ARGS_LIB_NAME ${PARSED_ARGS_PACKAGE})
endif()

find_program(CARGO NAMES cargo REQUIRED)
find_program(RUSTC NAMES rustc REQUIRED)

if(CMAKE_CONFIGURATION_TYPES)
message(
FATAL_ERROR
"Multi-config generators are not supported for Rust CCF applications"
)
endif()

if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CARGO_PROFILE_FLAG "")
set(CARGO_PROFILE_DIR debug)
else()
set(CARGO_PROFILE_FLAG --release)
set(CARGO_PROFILE_DIR release)
endif()

string(REPLACE "-" "_" RUST_LIB_NAME ${PARSED_ARGS_LIB_NAME})
get_filename_component(MANIFEST_PATH ${PARSED_ARGS_MANIFEST_PATH} ABSOLUTE)
get_filename_component(MANIFEST_DIR ${MANIFEST_PATH} DIRECTORY)
set(CARGO_TARGET_DIR ${CMAKE_CURRENT_BINARY_DIR}/cargo/${name})
set(
RUST_APP_LIB
${CARGO_TARGET_DIR}/${CARGO_PROFILE_DIR}/lib${RUST_LIB_NAME}.a
)

set(
RUSTFLAGS
"$ENV{RUSTFLAGS} --remap-path-prefix=${MANIFEST_DIR}=APP --remap-path-prefix=${CCF_DIR}=CCF --remap-path-prefix=$ENV{HOME}/.cargo=CARGO"
)
add_custom_target(
cargo-build_${name}
BYPRODUCTS ${RUST_APP_LIB}
COMMAND ${CMAKE_COMMAND} -E make_directory ${CARGO_TARGET_DIR}
COMMAND
${CMAKE_COMMAND} -E env --unset=CARGO_BUILD_TARGET
"RUSTFLAGS=${RUSTFLAGS}" "CARGO_NET_RETRY=10" "CARGO_HTTP_TIMEOUT=60"
"CC=${CMAKE_C_COMPILER}" "CXX=${CMAKE_CXX_COMPILER}" "AR=${CMAKE_AR}"
"CARGO_BUILD_RUSTC=${RUSTC}" ${CARGO} build --lib --package
${PARSED_ARGS_PACKAGE} --manifest-path ${MANIFEST_PATH} --target-dir
${CARGO_TARGET_DIR} ${CARGO_PROFILE_FLAG} --locked
WORKING_DIRECTORY ${MANIFEST_DIR}
COMMENT "Building Rust CCF application ${name}"
USES_TERMINAL
VERBATIM
)

if(EXISTS "${CCF_DIR}/src/rust/app_bridge.cpp")
set(RUST_BRIDGE_SOURCE "${CCF_DIR}/src/rust/app_bridge.cpp")
set(RUST_APP_MAIN_SOURCE "${CCF_DIR}/samples/apps/main.cpp")
else()
set(RUST_BRIDGE_SOURCE "${CCF_DIR}/share/ccf/rust/app_bridge.cpp")
set(RUST_APP_MAIN_SOURCE "${CCF_DIR}/share/ccf/rust/app_main.cpp")
endif()

add_ccf_app(
${name}
SRCS ${RUST_BRIDGE_SOURCE} ${RUST_APP_MAIN_SOURCE}
LINK_LIBS ${RUST_APP_LIB}
DEPS cargo-build_${name}
)
endfunction()

function(add_ccf_static_library name)
cmake_parse_arguments(PARSE_ARGV 1 PARSED_ARGS "" "" "SRCS;LINK_LIBS")

Expand Down
10 changes: 10 additions & 0 deletions cmake/gersemi_definitions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ function(add_ccf_app name)
)
endfunction()

function(add_ccf_rust_app name)
cmake_parse_arguments(
PARSE_ARGV 1
PARSED_ARGS
""
"MANIFEST_PATH;PACKAGE;LIB_NAME"
""
)
endfunction()

function(add_ccf_static_library name)
cmake_parse_arguments(PARSE_ARGV 1 PARSED_ARGS "" "" "SRCS;LINK_LIBS")
endfunction()
Expand Down
74 changes: 74 additions & 0 deletions doc/build_apps/example_rust.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
Example app (Rust)
==================

CCF provides an initial Rust interface for native applications. It deliberately
exposes a small subset of the public application API:

- read-write and read-only HTTP endpoints;
- user-certificate authentication or no authentication;
- request bodies, raw queries, decoded path parameters, and named headers;
- response status, headers, body, and OData errors; and
- raw-byte KV ``get``, ``has``, ``put``, and ``remove`` operations.

Advanced endpoint configuration, custom authentication, historical queries,
indexing, and commit callbacks are not currently exposed.

Build
-----

Rust 1.90 and Cargo are required. A Rust application is a ``staticlib`` crate
which depends on the source-tree ``src/rust/ccf-app`` crate or the installed
``share/ccf/src/rust/ccf-app`` crate. Its CMake file registers the crate with
``add_ccf_rust_app``:

.. code-block:: cmake

add_ccf_rust_app(
my_app
MANIFEST_PATH ${CMAKE_CURRENT_LIST_DIR}/Cargo.toml
PACKAGE my-app
)

The helper maps CMake ``Debug`` builds to Cargo's development profile and all
other build types to Cargo's release profile. It also links the generic C++ ABI
bridge, launcher, and CCF libraries. Cargo is invoked on every build and decides
whether the crate is up to date, so Rust source edits do not require CMake to be
reconfigured. ``LIB_NAME`` defaults to the package name with dashes replaced by
underscores; set it explicitly when the crate's ``[lib] name`` differs from its
package name. The application should commit ``Cargo.lock`` and pin a Rust
toolchain for reproducible builds.

The complete records example is in :ccf_repo:`samples/apps/basic_rust`. It
exports a registration function with ``ccf_app::export_app!`` and registers
handlers through ``Registry::read_write`` and ``Registry::read_only``.

Endpoint execution
------------------

Handlers may run concurrently and must be ``Send`` and ``Sync``. CCF may also
retry a read-write handler when a transaction conflicts, so handlers should be
deterministic and should not perform non-transactional side effects.

Request and response contexts, transactions, and map handles borrow the callback
context and cannot be retained. Values returned by KV ``get`` are owned copies.
The SDK requires Rust's ``unwind`` panic strategy so that panics are caught at
the ABI boundary and become HTTP 500 errors. Builds using ``panic = "abort"``
are rejected. C++ exceptions are also contained by the bridge.

KV values and keys
------------------

The initial API treats keys and values as byte strings. Applications may layer
their own serializers on these operations; the ``Codec`` trait provides a
common interface without prescribing a wire format.

Map names retain the standard CCF security semantics. Names beginning with
``public:`` are written to the ledger in plaintext. All other application map
names, such as the sample's ``records`` map, are private and encrypted. Like
native C++ applications, native Rust applications are trusted code: raw map
access does not enforce the namespace restrictions applied to JavaScript
applications for reserved governance and internal maps.

Read-only handlers receive only ``ReadOnlyMap``, so write operations are
not available at compile time. Errors returned by a handler use the normal CCF
transaction semantics: unsuccessful responses discard writes.
9 changes: 8 additions & 1 deletion doc/build_apps/get_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Application Development using CCF Overview

- :ref:`What is Confidential Consortium Framework (CCF) <overview/what_is_ccf:What is CCF?>`
- Read the :doc:`CCF overview </overview/index>` and get familiar with :ref:`overview/what_is_ccf:Core Concepts` and `Azure confidential computing <https://learn.microsoft.com/en-us/azure/confidential-computing/>`__
- :doc:`Build new CCF applications </build_apps/index>` in TypeScript/JavaScript or C++
- :doc:`Build new CCF applications </build_apps/index>` in TypeScript/JavaScript, C++, or Rust
- CCF `JavaScript module API reference <https://ccf.dev/main/js/ccf-app/>`__
- CCF application get started repos `CCF application template <https://github.com/microsoft/ccf-app-template>`__ and `CCF application samples <https://github.com/microsoft/ccf-app-samples>`__

Expand Down Expand Up @@ -91,6 +91,13 @@ Packaging your C++ app

To create distributable packages for your CCF application, create a ``cpack.cmake`` file that includes CCF's packaging configuration and add it to your ``CMakeLists.txt``. See :ccf_repo:`tests/ccfapp/CMakeLists.txt` and :ccf_repo:`tests/ccfapp/cpack.cmake` for a complete working example.

Rust Applications
-----------------

Rust applications are native CCF executables with the same deployment model as
C++ applications. See :doc:`example_rust` for the supported API and build
instructions.

Network Governance
------------------

Expand Down
10 changes: 9 additions & 1 deletion doc/build_apps/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ This section describes how CCF applications can be developed and deployed to a C

.. tip:: The `ccf-app-template <https://github.com/microsoft/ccf-app-template>`_ repository can be used to quickly build and run a sample CCF application and provides a minimal template to create new CCF apps.

Applications can be written in JavaScript/TypeScript or C++. An application consists of a collection of endpoints that can be triggered by :term:`Users`. Each endpoint can define an :ref:`build_apps/example_cpp:API Schema` to validate user requests.
Applications can be written in JavaScript/TypeScript, C++, or Rust. An application consists of a collection of endpoints that can be triggered by :term:`Users`. Each endpoint can define an :ref:`build_apps/example_cpp:API Schema` to validate user requests.

These endpoints can read or mutate the state of a unique :ref:`build_apps/kv/index:Key-Value Store` that represents the internal state of the application. Applications define a set of ``Maps`` (see :doc:`kv/kv_how_to`), mapping from a key to a value. When an application endpoint is triggered, the effects on the Store are committed atomically.

Expand Down Expand Up @@ -37,6 +37,13 @@ These endpoints can read or mutate the state of a unique :ref:`build_apps/kv/ind

---

:fa:`gear` :doc:`example_rust`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Minimal native CCF application written in Rust.

---

.. image:: ../img/ts.svg
:alt: TypeScript
:align: left
Expand Down Expand Up @@ -110,6 +117,7 @@ These endpoints can read or mutate the state of a unique :ref:`build_apps/kv/ind
get_started
install_bin
example
example_rust
js_app_ts
js_app_bundle
logging
Expand Down
23 changes: 23 additions & 0 deletions include/ccf/kv/compacted_version_conflict.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the Apache 2.0 License.
#pragma once

#include <string>
#include <utility>

namespace ccf::kv
{
class CompactedVersionConflict
{
private:
std::string msg;

public:
CompactedVersionConflict(std::string s) : msg(std::move(s)) {}

[[nodiscard]] char const* what() const
{
return msg.c_str();
}
};
}
Loading