Official Allow2 Parental Freedom SDK for C++. A modern C++ wrapper around liballow2, providing RAII, type safety, and idiomatic C++ patterns.
| Library | liballow2pp (static .a / .lib) |
| Targets | Linux (gcc 11+), macOS (clang 13+), Windows (MSVC 2019+) |
| Dependencies | liballow2 |
| Standard | C++17 |
Download the prebuilt static library and headers for your platform from GitHub Releases.
# Clone with liballow2 dependency
git clone https://github.com/Allow2/liballow2.git
git clone https://github.com/Allow2/allow2cpp.git
cd allow2cpp
mkdir build && cd build
cmake .. -DLIBALLOW2_DIR=../../liballow2
make
sudo make installfind_package(allow2pp REQUIRED)
target_link_libraries(your_target PRIVATE allow2pp::allow2pp)#include <allow2/daemon.hpp>
#include <allow2/models.hpp>
#include <iostream>
int main() {
allow2::Daemon daemon({
.device_name = "Living Room PC",
.activities = {{1}, {8}}, // Internet + Screen Time
});
daemon.on_pairing_required([](const allow2::PairingInfo& info) {
std::cout << "Enter PIN: " << info.pin << "\n";
});
daemon.on_child_select_required([](const std::vector<allow2::Child>& children) {
std::cout << "Select a child (" << children.size() << " available)\n";
});
daemon.on_warning([](const allow2::Warning& w) {
std::cout << "Warning: " << w.level << ", " << w.remaining << "s left\n";
});
daemon.on_soft_lock([](const std::string& reason) {
std::cout << "Time is up: " << reason << "\n";
});
daemon.start();
daemon.run(); // blocks on event loop
return 0;
}| Module | Header | Purpose |
|---|---|---|
| Daemon | daemon.hpp |
RAII orchestrator managing the full device lifecycle |
| ChildShield | child_shield.hpp |
PIN hashing (SHA-256 + salt), rate limiting, session timeout |
| Checker | checker.hpp |
Permission check loop with per-activity enforcement |
| Feedback | feedback.hpp |
Submit/load/reply to feedback discussions |
| Models | models.hpp |
Type-safe structs for all API types |
The C++ SDK delegates HTTP, pairing, crypto, warnings, offline handling, and request management to the underlying liballow2 C library.
// The check loop runs automatically once a child is selected.
// Results arrive via callback:
daemon.on_check_result([](const allow2::CheckResult& result) {
for (const auto& activity : result.activities) {
std::cout << activity.id << ": allowed=" << activity.allowed
<< ", remaining=" << activity.remaining << "s\n";
}
std::cout << "Today: " << result.day_type_today
<< ", Tomorrow: " << result.day_type_tomorrow << "\n";
});auto result = daemon.request_more_time({
.activity = 3, // Gaming
.duration = 30, // minutes
.message = "Can I please have more time?",
});
auto status = daemon.poll_request_status(result.request_id, result.status_secret);
if (status.approved) {
std::cout << "Approved! " << status.duration << " extra minutes.\n";
} else {
std::cout << "Request denied.\n";
}auto result = daemon.submit_feedback({
.category = allow2::FeedbackCategory::NotWorking,
.message = "The block screen appears even when time is remaining.",
});
auto feedback = daemon.load_device_feedback();
daemon.reply_to_feedback(result.discussion_id, "This happens every Tuesday.");The SDK inherits credential storage from liballow2 (defaults to ~/.allow2/credentials.json with 0600 permissions).
For custom storage, provide callbacks via the config:
allow2::Daemon daemon({
.device_name = "My Device",
.activities = {{1}, {8}},
.credential_load = []() -> std::optional<allow2::Credentials> {
// Load from secure storage
},
.credential_store = [](const allow2::Credentials& creds) {
// Persist credentials
},
.credential_clear = []() {
// Remove credentials
},
});| Platform | Compiler | Notes |
|---|---|---|
| Linux | gcc 11+ | Steam Deck, desktop, embedded |
| macOS | Apple clang 13+ | Universal binaries (x86_64 + arm64) |
| Windows | MSVC 2019+ | Static linking |
| Game Engines | Unreal (C++17) | Via static library linking |
The SDK follows the Allow2 Device Operational Lifecycle:
- Pairing (one-time) -- QR code or 6-digit PIN, parent never enters credentials on device
- Child Identification (every session) -- OS account mapping, child selector with PIN, or verification via the child's Allow2 app (iOS/Android) or web portal
- Parent Access -- parent verifies via their Allow2 app (iOS/Android), web portal, or locally with PIN for unrestricted mode
- Permission Checks (continuous) -- POST to service URL every 30-60s with
log: true - Warnings & Countdowns -- progressive alerts before blocking
- Requests -- child requests changes (more time, day type change, ban lift), parent approves/denies from their phone (also works offline via voice codes)
- Feedback -- bug reports and feature requests sent directly to you, the developer
The C++ SDK is a thin RAII wrapper around liballow2. All network operations, crypto, and JSON handling are performed by the C library. The C++ layer adds type safety, RAII lifecycle management, lambda callbacks, and std:: containers.
Environment overrides via ALLOW2_API_URL, ALLOW2_VID, and ALLOW2_TOKEN environment variables.
Once a device is paired, Allow2 remains fully configurable even when the device is offline. The parent can still manage the child's limits, approve requests, and change settings from their Allow2 app or the web portal -- changes are synchronised the next time the device connects.
On the device side:
- Cached permissions -- the last successful check result is cached locally. During a configurable grace period (default 5 minutes), the device continues to enforce the cached result.
- Deny-by-default -- after the grace period expires without connectivity, all activities are blocked. This prevents children from bypassing controls by disabling Wi-Fi or enabling airplane mode.
- Requests (offline) -- children can still submit all request types (more time, day type change, ban lift) even when the device is offline. The request is presented to the parent via their app or a voice code that can be read over the phone. The parent approves or denies from their end, and the device applies the result when connectivity resumes (or immediately via a voice code response entered locally).
- Automatic resync -- when the device comes back online, it immediately fetches the latest permissions, processes any queued requests, and resumes normal check polling.
This means a paired device is never "unmanageable" -- the parent always has control, regardless of the device's network state.
See LICENSE for details.