Skip to content

Added MAVLink 2.0 message signing and authentication support to provide secure communication between GCS and flight controller.#1038

Open
PritamP20 wants to merge 5 commits into
ArduPilot:masterfrom
PritamP20:feature/mavlink-signing-backend
Open

Added MAVLink 2.0 message signing and authentication support to provide secure communication between GCS and flight controller.#1038
PritamP20 wants to merge 5 commits into
ArduPilot:masterfrom
PritamP20:feature/mavlink-signing-backend

Conversation

@PritamP20
Copy link
Copy Markdown
Contributor

Summary

This PR adds MAVLink 2.0 message signing and authentication support to provide secure communication between the ground control station and flight controller.

Motivation

MAVLink signing is essential for:

  • Security: Protect against unauthorized parameter changes and message injection
  • Compliance: Required for commercial drone operations in many jurisdictions
  • Safety: Prevent malicious actors from taking control of vehicles

Changes

New Files

  • ardupilot_methodic_configurator/backend_signing_keystore.py (450 lines)

    • Secure key storage using OS keyring with encrypted file fallback
    • Key generation, storage, retrieval, deletion
    • Password-protected import/export
  • ardupilot_methodic_configurator/data_model_signing_config.py (150 lines)

    • Configuration data model with validation
    • Serialization/deserialization
  • tests/test_signing_keystore.py (15 test cases)

  • tests/test_signing_config.py (15 test cases)

  • docs/mavlink_signing/ (complete documentation)

  • install_signing_dependencies.sh - Installation script

Modified Files

  • ardupilot_methodic_configurator/backend_flightcontroller.py

    • Added setup_signing() method
    • Added _send_setup_signing_command() method
    • Added _unsigned_callback() method
    • Added get_signing_status() method
  • pyproject.toml

    • Added cryptography>=41.0.0 dependency
    • Added keyring>=24.0.0 dependency

Features

Security

  • ✅ HMAC-SHA-256 message signing (authentication, not encryption)
  • ✅ OS keyring integration (Windows/macOS/Linux)
  • ✅ AES-256 encrypted file fallback
  • ✅ Cryptographically secure key generation
  • ✅ Password-protected key export/import
  • ✅ Per-vehicle key isolation
  • ✅ Timestamp-based replay protection

Key Management

  • ✅ Generate cryptographically secure 32-byte keys
  • ✅ Store keys securely per vehicle
  • ✅ Retrieve keys for signing setup
  • ✅ Delete keys when no longer needed
  • ✅ List all vehicles with configured keys
  • ✅ Export/import keys with password protection

@amilcarlucas
Copy link
Copy Markdown
Collaborator

Thanks, thiswill take a while to review. Have you tested this in multiple vehicles?

@PritamP20
Copy link
Copy Markdown
Contributor Author

Yes, I’ve tested it with multiple vehicle entries using the test_multiple_vehicles and test_list_vehicles_with_keys unit tests. These tests cover storing, retrieving, and managing keys for different vehicle IDs to ensure proper isolation and persistence between them.

@PritamP20
Copy link
Copy Markdown
Contributor Author

Hi @amilcarlucas, just wanted to check in if you’ve had a chance to review this PR. Please let me know if there’s anything I should update or clarify further.

@amilcarlucas
Copy link
Copy Markdown
Collaborator

amilcarlucas commented Nov 13, 2025

Thanks for working on this

  1. It needs to be tested on real hardware. Real multiple flight controllers.
  2. The two git commits on this branch should be squashed and the commit message should start with "feat(mavlink signing):"
  3. The tests should follow BDD practices as defined in the pytest_testing_instructions.md file.
  4. The two new SW dependencies must be added to LICENSES.md and CREDITS.md
  5. The CI tests bellow need to all pass (ruff, mypy, pyright, pylint pytest, ... etc)
  6. Please do not work on Phase 2 until this PR is merged.

@PritamP20
Copy link
Copy Markdown
Contributor Author

PritamP20 commented Nov 13, 2025

Okay @amilcarlucas,
Thank you for your feedback on this PR. While Phase 2 is on hold until this PR is merged, I wanted to check if there are any other features or tasks I could work on in this repo. Additionally, if there are other repositories in the organization where I could contribute

@amilcarlucas
Copy link
Copy Markdown
Collaborator

amilcarlucas commented Nov 13, 2025

Currently my priority is "refactoring for testability". I want to add more tests to the code, and in some parts of the code that is only possible by refactoring it first before the tests can be added. Doing it like this leads to better code and better tests. But there is no need to duplicate the efforts on that.

You could work on adding a new plugin, similar to the "motor test" plugin that does RC receiver calibration. Take a look at ARCHITECTURE_motor_test.md for inspiration. It should mimic the RC receiver calibration screen from mission planner. If you work on that we will not duplicate efforts.

Do try to finish this one first, so that you can learn more on the workflow of the project. Are you developing on Linux, or Windows?

@amilcarlucas
Copy link
Copy Markdown
Collaborator

amilcarlucas commented Nov 27, 2025

@PritamP20 any progress on this?
We now have automated SITL tests that can be used to test this feature realistically. An ArduCopter SITL instance runs in CI and your tests can communicate with it

@PritamP20
Copy link
Copy Markdown
Contributor Author

yup working on it @amilcarlucas
I will update the pr soon

@amilcarlucas
Copy link
Copy Markdown
Collaborator

Any progress on this?

@PritamP20
Copy link
Copy Markdown
Contributor Author

Yup some errors to resolve,
will raise it soon by today or tmr (had some health issues lately really sorry for the delay)

@PritamP20 PritamP20 closed this Jan 7, 2026
@PritamP20 PritamP20 force-pushed the feature/mavlink-signing-backend branch from 0422335 to dcbd034 Compare January 7, 2026 09:47
@PritamP20
Copy link
Copy Markdown
Contributor Author

Hi @amilcarlucas, I've added SITL integration tests in
tests/integration_signing_sitl.py
marked with @pytest.mark.integration.

You mentioned there's already an ArduCopter SITL instance in CI - could you clarify

@amilcarlucas
Copy link
Copy Markdown
Collaborator

SITL tests are available in tests/sitl_*.py files.
These tests are very slow (20 seconds per test) but they do fully test real mavlink communication with a real SITL.

Take a look at the files for inspiration. Not all the tests need to be sitl tests, but the main functionality should be tested with SITL because that is the only way to be sure that the signing is really working.

@PritamP20
Copy link
Copy Markdown
Contributor Author

understood, making some changes right now, if i have any doubts i will reach out to you back

@PritamP20 PritamP20 reopened this Jan 8, 2026
@PritamP20
Copy link
Copy Markdown
Contributor Author

Hi @amilcarlucas,
I’ve updated the PR with all the requested changes:

Changes Made:

  • Tests now follow BDD practices (GIVEN/WHEN/THEN format)
  • Added cryptography and keyring to CREDITS.md
  • Squashed into a single commit with feat(mavlink signing): prefix
  • Rebased on latest upstream/master (now includes SITL infrastructure)
  • Added SITL integration tests in tests/sitl_signing.py

Test Results:

  • All 33 unit tests pass locally
  • mypy/pyright: no type errors

Regarding SITL Testing:
I’m developing on macOS, and the pre-built SITL binaries from firmware.ardupilot.org are Linux-only (causing an Exec format error when run locally). The SITL integration tests are properly marked and should execute in the CI environment on Linux.

Could you confirm if the CI SITL tests pass after your review?
If needed, I can build SITL from source, though that would take some additional time.

Thanks!

@PritamP20
Copy link
Copy Markdown
Contributor Author

@amilcarlucas do you have any suggestions on this? I’m currently working on setting up and running the SITL tests on macOS.

@PritamP20 PritamP20 force-pushed the feature/mavlink-signing-backend branch 2 times, most recently from 57f2b85 to 552279a Compare January 10, 2026 12:00
@amilcarlucas
Copy link
Copy Markdown
Collaborator

execute :

./scripts/run_sitl_tests.sh setup

And the sitl should get automatically setup

@PritamP20
Copy link
Copy Markdown
Contributor Author

@amilcarlucas I tried running it —
./scripts/run_sitl_tests.sh download works fine, but when I run

./scripts/run_sitl_tests.sh run

I get an error because the script has hardcoded Linux paths in the download_sitl() function (around line 112). It doesn’t detect macOS properly, so it ends up trying to download the Linux binaries instead.

I’m currently working on adapting the script for macOS. If that doesn’t work out, I’ll look for an alternative way to run the tests.

@PritamP20
Copy link
Copy Markdown
Contributor Author

I was just wondering wouldn’t it make sense to dockerize the application? That way, anyone could run and test everything consistently across different environments

@amilcarlucas amilcarlucas force-pushed the feature/mavlink-signing-backend branch 3 times, most recently from f75ddbb to 31be8e2 Compare January 11, 2026 21:16
@amilcarlucas
Copy link
Copy Markdown
Collaborator

I fixed the linting errors and improved test coverage to 90%
The bdd tests are now in bdd_prefixed files
Unit tests are in file prefixed with unit_

There are more bdd than unit tests, that is deliberated.

No, I do not think docker is good for the final users. But it might be good for developers.

@amilcarlucas
Copy link
Copy Markdown
Collaborator

SITL tests now work correctly.

@amilcarlucas amilcarlucas changed the title Featuer: added MAVLink 2.0 message signing and authentication support to provide secure communication between GCS and flight controller. Added MAVLink 2.0 message signing and authentication support to provide secure communication between GCS and flight controller. Jan 11, 2026
amilcarlucas pushed a commit to PritamP20/MethodicConfigurator that referenced this pull request Feb 1, 2026
Implement secure communication between ground control station and flight
controller using HMAC-SHA256 message signing to prevent tampering and
message injection attacks.

New Components:
- backend_flightcontroller: setup_signing(), disable_signing(),
  get_signing_status() methods for MAVLink signing management
- backend_signing_config: configuration persistence with atomic file
  operations and cross-platform locking
- backend_signing_keystore: secure key storage using OS keyring with
  encrypted file fallback

Security Features:
- 32-byte (256-bit) cryptographic signing keys
- Timestamp-based replay attack prevention (7-day validation window)
- OS-native keyring support (Windows Credential Manager, macOS Keychain,
  Linux Secret Service)
- Secure file fallback with AES-256 encryption and restrictive permissions
  (0o600 on Unix)
- Per-vehicle key isolation

Documentation:
- Added comprehensive OS keyring setup guide in INSTALL.md
- Security warnings about file-based fallback limitations
- Platform-specific installation instructions

Implementation Details:
- Configurable signing modes (sign_outgoing, allow_unsigned_in)
- Permissive unsigned message handling during setup phase
- Specific exception handling for file operations
- Type-safe implementation with full type hints
- Extensive validation (key length, link_id range, timestamp age)

Related: ArduPilot#1038

Signed-off-by: PritamP20 <pripritam7@gmail.com>
@amilcarlucas amilcarlucas force-pushed the feature/mavlink-signing-backend branch 2 times, most recently from c9a4704 to a888ad4 Compare February 1, 2026 21:04
@amilcarlucas
Copy link
Copy Markdown
Collaborator

The commits have been squashed, conflicts solved and rebased.
I use AI to review the changes and it found a bunch of security issues and flaws. I addressed tham.

Please test this version of the code and review the changes I did to it.

@PritamP20
Copy link
Copy Markdown
Contributor Author

@amilcarlucas sure i will check them and get back to you

@PritamP20
Copy link
Copy Markdown
Contributor Author

@amilcarlucas I checked everything, everything looks fine and the tests are also passing both SITL and unit tests

@amilcarlucas
Copy link
Copy Markdown
Collaborator

amilcarlucas commented Feb 3, 2026

I mean tests or real hardware, to be 100% sure it works before merging 3800 lines of code.

@PritamP20
Copy link
Copy Markdown
Contributor Author

I totally get the concern given the size of the PR. To make sure everything’s reliable without depending on physical flights, I set up a thorough verification process:

Unit & BDD Tests — Added 94 tests covering 100% of the core storage, encryption, and persistence logic, including edge cases like permission errors and data corruption.

SITL Integration — Ran full end-to-end integration tests on a Dockerized ArduCopter SITL setup. Since SITL runs the actual production AP_Flight code, it validates the MAVLink signing handshake and authentication logic exactly as it would on real hardware.

All 102 tests passed successfully.

@amilcarlucas
Copy link
Copy Markdown
Collaborator

So you do not have any real flight controller to test this on?

@PritamP20
Copy link
Copy Markdown
Contributor Author

I don’t have access to any real flight controller hardware right now, but the SITL setup I used runs the same ArduPilot firmware stack and fully validates the MAVLink signing and authentication flow at the protocol level so the behavior should be identical to real hardware


This class provides secure storage for signing keys using:
1. OS keyring (preferred) - Windows Credential Manager, macOS Keychain, Linux Secret Service
2. Encrypted file fallback - AES-256 encrypted JSON file
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to have a fallback? If the users want a signing, they will surely have a keystore setup, right?

@PritamP20
Copy link
Copy Markdown
Contributor Author

@amilcarlucas I’ll look into the requested changes. By the way, I’m applying for GSoC 2026 with ArduPilot would you be open to mentoring me? I’d love to continue working on this feature and contributing to this repository.

@amilcarlucas
Copy link
Copy Markdown
Collaborator

Yes, I will gladly mentor you.

@PritamP20
Copy link
Copy Markdown
Contributor Author

Thank you, @amilcarlucas. I’ll be preparing a GSoC proposal for ArduPilot alongside my work on this feature, and I’d appreciate your review and feedback when it’s ready

@PritamP20
Copy link
Copy Markdown
Contributor Author

Hi @amilcarlucas,
Just checking in to see if there are any updates or further changes you'd like me to make on this PR.
Everything on my side is up to date and verified, but I’m happy to adjust or retest anything if needed.

@amilcarlucas
Copy link
Copy Markdown
Collaborator

Please remove the " Encrypted file fallback - AES-256 encrypted JSON file". It just adds complexity with little added benefit, if the users want to use this they need to install and configure a proper keyring.

@amilcarlucas
Copy link
Copy Markdown
Collaborator

amilcarlucas commented Mar 24, 2026

Any progress on this? It is very close to get merged, just remove the fallback code for the local file.

If you finish the feature, I will take care of the rebase and the merge conflicts for you.

@PritamP20
Copy link
Copy Markdown
Contributor Author

@amilcarlucas I will do them and push it

Implement secure communication between ground control station and flight
controller using HMAC-SHA256 message signing to prevent tampering and
message injection attacks.

New Components:
- backend_flightcontroller: setup_signing(), disable_signing(),
  get_signing_status() methods for MAVLink signing management
- backend_signing_config: configuration persistence with atomic file
  operations and cross-platform locking
- backend_signing_keystore: secure key storage using OS keyring with
  encrypted file fallback

Security Features:
- 32-byte (256-bit) cryptographic signing keys
- Timestamp-based replay attack prevention (7-day validation window)
- OS-native keyring support (Windows Credential Manager, macOS Keychain,
  Linux Secret Service)
- Secure file fallback with AES-256 encryption and restrictive permissions
  (0o600 on Unix)
- Per-vehicle key isolation

Documentation:
- Added comprehensive OS keyring setup guide in INSTALL.md
- Security warnings about file-based fallback limitations
- Platform-specific installation instructions

Implementation Details:
- Configurable signing modes (sign_outgoing, allow_unsigned_in)
- Permissive unsigned message handling during setup phase
- Specific exception handling for file operations
- Type-safe implementation with full type hints
- Extensive validation (key length, link_id range, timestamp age)

Related: ArduPilot#1038

Signed-off-by: PritamP20 <pripritam7@gmail.com>
Copilot AI review requested due to automatic review settings May 4, 2026 20:47
@amilcarlucas amilcarlucas force-pushed the feature/mavlink-signing-backend branch from a888ad4 to e802e96 Compare May 4, 2026 20:47
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR introduces MAVLink 2.0 signing support (configuration model + persistence + key storage) and adds extensive tests/documentation to enable authenticated GCS↔FC communication.

Changes:

  • Added signing configuration data model + JSON/schema-based persistence manager.
  • Added OS keyring-backed signing keystore and FlightController APIs for setup/disable/status.
  • Added broad unit/integration/BDD/SITL tests plus docs and tooling updates.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 16 comments.

Show a summary per file
File Description
tests/unit_data_model_signing_config.py Adds unit tests for signing config validation and manager error handling.
tests/signing_test_fixtures.py Adds shared fixtures/constants for signing-related tests.
tests/integration_signing_config_advanced.py Adds advanced integration tests for serialization/equality/error paths.
tests/integration_data_model_signing_config.py Adds integration tests for data model workflows and edge cases.
tests/integration_backend_signing_config.py Adds integration tests for config persistence backend behavior.
tests/bdd_signing_sitl_integration.py Adds SITL tests for signing workflows against ArduPilot SITL.
tests/bdd_data_model_signing_config.py Adds BDD-style tests for signing config + persistence scenarios.
tests/bdd_backend_signing_keystore.py Adds BDD-style tests for keyring keystore behavior via mocking.
tests/bdd_backend_flightcontroller_signing.py Adds BDD-style tests for FlightController signing APIs.
scripts/run_sitl_tests.sh Extends SITL test runner to include signing SITL integration tests.
pyproject.toml Adds keyring dependency for OS credential storage.
credits/CREDITS.md Adds keyring attribution/license entry.
ardupilot_methodic_configurator/schema_signing_config.json Adds JSON schema for signing config persistence format.
ardupilot_methodic_configurator/data_model_signing_config.py Introduces SigningConfig + VehicleSigningConfig datamodels.
ardupilot_methodic_configurator/backend_signing_keystore.py Introduces keyring-based SigningKeystore (generate/store/retrieve/delete/rotate).
ardupilot_methodic_configurator/backend_signing_config.py Adds SigningConfigManager with load/save/delete/list and file-locking atomic writes.
ardupilot_methodic_configurator/backend_flightcontroller.py Adds setup_signing/disable_signing/get_signing_status and unsigned callback.
INSTALL.md Documents OS keyring setup requirements for signing.

Comment thread tests/bdd_signing_sitl_integration.py Outdated
Comment on lines +37 to +41
def signing_keystore(tmp_path) -> SigningKeystore:
"""Create a signing keystore with temporary storage."""
with patch("ardupilot_methodic_configurator.backend_signing_keystore.user_data_dir") as mock_dir:
mock_dir.return_value = str(tmp_path)
return SigningKeystore(use_keyring=False)
else:
# Windows file locking using msvcrt
import msvcrt # noqa: PLC0415 # pylint: disable=import-outside-toplevel,import-error

Comment on lines +228 to +233
# Now perform file operations under lock protection
with open(temp_file, "w", encoding="utf-8") as f:
json.dump(configs, f, indent=2)

# Atomic rename
os.replace(temp_file, config_file)
Comment on lines +518 to +519
sign_outgoing: bool = True,
allow_unsigned_in: bool = True,
self.master.setup_signing( # type: ignore[union-attr]
key,
sign_outgoing=sign_outgoing,
allow_unsigned_callback=self._unsigned_callback if allow_unsigned_in else None,
Comment thread tests/bdd_backend_signing_keystore.py Outdated
Comment on lines +19 to +25
# Mock keyring before importing SigningKeystore
mock_keyring = MagicMock()
mock_backend = MagicMock()
mock_keyring.get_keyring.return_value = mock_backend
mock_keyring.set_password = MagicMock()
mock_keyring.get_password = MagicMock()
mock_keyring.delete_password = MagicMock()
Comment thread tests/bdd_backend_signing_keystore.py Outdated
Comment on lines +41 to +42
sys.modules["keyring"] = mock_keyring
sys.modules["keyring.errors"] = mock_keyring.errors
Comment thread pyproject.toml
Comment on lines 48 to 54
"certifi==2026.4.22",
"defusedxml==0.7.1",
"jsonschema==4.25.1",
"keyring==25.6.0",
"matplotlib==3.9.4; python_version < '3.10'",
"matplotlib==3.10.3; python_version >= '3.10' and python_version < '3.14'",
"matplotlib==3.10.7; python_version >= '3.14'",
Comment on lines +21 to +26
class SigningKeystore:
"""
Secure keystore for MAVLink 2.0 signing keys using OS keyring.

This class provides secure storage for signing keys using the operating system's
native keyring/credential storage:
- Cryptographically secure key generation using secrets module
- Per-vehicle key isolation
- Integration with OS-level security infrastructure
- No weak fallbacks or obfuscation
@amilcarlucas amilcarlucas force-pushed the feature/mavlink-signing-backend branch from e802e96 to 75284da Compare May 4, 2026 21:42
@amilcarlucas
Copy link
Copy Markdown
Collaborator

It's rebased, and the filesystem fallback code removed, and even more tests added.
@PritamP20 Are you going to continue working on this to add a GUI ?

@amilcarlucas amilcarlucas force-pushed the feature/mavlink-signing-backend branch from 75284da to 7e73bfb Compare May 4, 2026 21:48
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.

3 participants