C++ SDK
The Authgate C++ SDK is a header-only client library that you can drop directly into your C++ application.
Installation
- Download
authgate_api.hppandauthgate_api.cppfrom your Authgate purchase - Copy them into your project directory
- Include the header in your code
Requirements:
- C++17 or higher
- libcurl (for HTTP requests)
- OpenSSL (for file encryption/decryption)
- nlohmann/json (for JSON parsing)
Install dependencies:
Ubuntu/Debian:
sudo apt-get install libcurl4-openssl-dev libssl-dev nlohmann-json3-devmacOS:
brew install curl openssl nlohmann-jsonWindows (vcpkg):
vcpkg install curl openssl nlohmann-jsonQuick Start
#include "authgate_api.hpp"
#include <iostream>
int main() {
// Initialize the client
authgate::AuthgateAPI client(
"https://your-authgate.com/api/integration",
"your-api-key",
"your-api-secret",
"your-base64-encryption-key",
"your-base64-signing-key",
true, // Enable request signing
"your-base64-response-signing-key",
true // Enable response signing
);
try {
// Login with username and password
auto auth = std::make_unique<authgate::TokenAuthStrategy>(
"username", "password"
);
client.login(std::move(auth));
// Get app context
authgate::AppContext context = client.get_app_context();
std::cout << "Connected to: " << context.application.name << std::endl;
// Check membership
if (context.user.has_value() && context.user->membership.is_active) {
std::cout << "User has active membership!" << std::endl;
}
} catch (const authgate::AuthenticationError& e) {
std::cerr << "Login failed: " << e.what() << std::endl;
} catch (const authgate::TimedOutError& e) {
std::cerr << "Access paused until: " << e.get_timed_out_until() << std::endl;
} catch (const authgate::AuthorizationError& e) {
std::cerr << "Access denied: " << e.what() << std::endl;
}
return 0;
}Compilation
Using g++:
g++ -std=c++17 main.cpp authgate_api.cpp -o myapp -lcurl -lssl -lcryptoUsing CMake:
find_package(CURL REQUIRED)
find_package(OpenSSL REQUIRED)
find_package(nlohmann_json REQUIRED)
add_executable(myapp main.cpp authgate_api.cpp)
target_link_libraries(myapp CURL::libcurl OpenSSL::SSL OpenSSL::Crypto nlohmann_json::nlohmann_json)Authentication
The SDK supports two authentication strategies:
TokenAuthStrategy (Recommended)
Gets a session token on login and automatically refreshes it when needed.
// Login with username/password
auto auth = std::make_unique<authgate::TokenAuthStrategy>(
"username", "password"
);
client.login(std::move(auth));
// Login with license code
auto auth = std::make_unique<authgate::TokenAuthStrategy>(
"", "", "LICENSE-CODE"
);
client.login(std::move(auth));
// Login with device authentication (if enabled)
auto auth = std::make_unique<authgate::TokenAuthStrategy>(
"username", "password", "", "device-hardware-id"
);
client.login(std::move(auth));LegacyAuthStrategy
Sends credentials with every request.
auto auth = std::make_unique<authgate::LegacyAuthStrategy>(
"username", "password"
);
client.login(std::move(auth));Common Operations
Check Membership Status
authgate::AppContext context = client.get_app_context();
if (context.user.has_value() && context.user->membership.is_active) {
// User has access
} else {
// Show upgrade prompt
}Show Remaining Time
active_until is the UTC time the membership expires. Compare it against
context.server_time — not the local clock — so the result is correct even if the
device clock is wrong or tampered with.
authgate::AppContext context = client.get_app_context();
const auto& membership = context.user->membership;
if (membership.is_lifetime) {
std::cout << "Lifetime access" << std::endl;
} else if (membership.active_until) {
std::cout << "Active until: " << *membership.active_until
<< " (server time: " << context.server_time << ")" << std::endl;
}Activate a License
try {
authgate::MembershipLicenseAdjustment adjustment =
client.activate_license("LICENSE-CODE", "username", "password");
if (adjustment.grants_lifetime_access) {
std::cout << "Lifetime license activated!" << std::endl;
} else if (adjustment.minutes.has_value()) {
std::cout << "Added " << *adjustment.minutes << " minutes" << std::endl;
}
} catch (const authgate::ValidationError& e) {
std::cerr << "Invalid license code" << std::endl;
}Download Files
// Download and decrypt a file
std::vector<uint8_t> file_data = client.download_file(
"file-uuid",
true, // decrypt
"config.json" // optional: save to disk
);
std::cout << "Downloaded " << file_data.size() << " bytes" << std::endl;Access Server Variables
authgate::AppContext context = client.get_app_context();
for (const auto& variable : context.application.variables) {
std::cout << variable.name << ": " << variable.value << std::endl;
}Access Announcements
The app context contains announcements that are currently published and visible. Content is provided as HTML for your application to display.
authgate::AppContext context = client.get_app_context();
for (const auto& announcement : context.announcements) {
std::cout << announcement.title << std::endl;
std::cout << announcement.content_html << std::endl;
}Call get_app_context() again to refresh the list. See Announcements for publication and scheduling options.
User Variables
Store and retrieve per-user data that syncs across devices:
// Set a user variable (creates if doesn't exist)
client.set_user_variable("theme", "dark");
// Get a single user variable
std::string theme = client.get_user_variable("theme");
// List all user variables
std::vector<authgate::UserVariable> vars = client.get_user_variables();
for (const auto& var : vars) {
std::cout << var.name << ": " << var.value << std::endl;
}Error Handling
The SDK uses exception classes for different error types:
try {
client.get_app_context();
} catch (const authgate::AuthenticationError& e) {
std::cerr << "Authentication failed - wrong credentials or not logged in" << std::endl;
} catch (const authgate::TimedOutError& e) {
std::cerr << "Access paused until " << e.get_timed_out_until() << std::endl;
if (!e.get_reason().empty()) {
std::cerr << "Reason: " << e.get_reason() << std::endl;
}
} catch (const authgate::AuthorizationError& e) {
// Check specific error code
std::string error_code = e.get_error_code();
if (error_code == "BANNED") {
std::cerr << "Account banned" << std::endl;
} else if (error_code == "INACTIVE_MEMBERSHIP") {
std::cerr << "Membership expired" << std::endl;
} else {
std::cerr << "Access denied" << std::endl;
}
} catch (const authgate::ValidationError& e) {
// Get field-specific errors
auto errors = e.get_validation_errors();
for (const auto& [field, message] : errors) {
std::cerr << field << ": " << message << std::endl;
}
} catch (const authgate::NetworkError& e) {
std::cerr << "Connection failed" << std::endl;
} catch (const authgate::AuthgateApiError& e) {
std::cerr << "API error: " << e.what() << std::endl;
}Catch TimedOutError before AuthorizationError. It provides the ISO 8601 expiry time and the optional reason entered by the admin.
Device Authentication
If device authentication is enabled on your application, you must provide a hardware_id when logging in or signing up:
During Login:
// Generate a unique hardware ID for this device
// (e.g., MAC address, CPU serial, or composite hash)
std::string hardware_id = "00:1B:44:11:3A:B7";
auto auth = std::make_unique<authgate::TokenAuthStrategy>(
"username", "password", "", hardware_id
);
client.login(std::move(auth));During Sign-Up:
// Sign up with username/password and register device
std::string hardware_id = "00:1B:44:11:3A:B7";
authgate::User user = client.sign_up("username", "password", hardware_id);
// Sign up with license code and register device
authgate::User user = client.sign_up_with_license_code("LICENSE-CODE", hardware_id);API Reference
AuthgateAPI Class
Constructor:
AuthgateAPI(
const std::string& base_url, // Your Authgate API URL
const std::string& api_key, // Application API key
const std::string& api_secret, // Application API secret
const std::string& files_encryption_key, // Base64 encryption key
const std::string& request_signing_key, // Base64 signing key
bool request_signing_enabled,
const std::string& response_signing_key, // Base64 response signing key
bool response_signing_enabled,
bool verify_ssl = true // Set false for self-signed certs
)Methods:
void login(std::unique_ptr<AuthStrategy> auth_strategy)- Authenticate uservoid logout()- Clear authenticationAppContext get_app_context()- Get application, announcements, and user infoUser sign_up(const std::string& username, const std::string& password, const std::string& hardware_id = "")- Create accountUser sign_up_with_license_code(const std::string& code, const std::string& hardware_id = "")- Create account with licenseMembershipLicenseAdjustment activate_license(...)- Activate a licensestd::vector<uint8_t> download_file(...)- Download a filestd::string get_user_variable(const std::string& name)- Get a user variablevoid set_user_variable(const std::string& name, const std::string& value)- Set a user variablestd::vector<UserVariable> get_user_variables()- List all user variables
Data Structures
struct Variable {
std::string name;
std::string value;
};
struct File {
std::string id; // UUID
std::string name;
std::string mime_type;
bool is_encrypted;
};
struct Application {
std::string id;
std::string name;
std::vector<Variable> variables;
std::vector<File> files;
};
struct Membership {
bool is_active;
bool is_lifetime;
std::optional<std::string> active_until; // ISO 8601 UTC, empty if lifetime/none
};
struct User {
std::string id;
std::string username;
Membership membership;
};
struct AppContext {
Application application;
std::optional<User> user;
std::string server_time; // ISO 8601 UTC, anchor for active_until
};Complete Example
#include "authgate_api.hpp"
#include <iostream>
int main() {
authgate::AuthgateAPI client(
"https://auth.myapp.com/api/integration",
"api-key",
"api-secret",
"encryption-key",
"signing-key",
true,
"response-signing-key",
true
);
try {
// Login
auto auth = std::make_unique<authgate::TokenAuthStrategy>(
"username", "password"
);
client.login(std::move(auth));
// Check access
authgate::AppContext context = client.get_app_context();
if (context.user.has_value() &&
context.user->membership.is_active) {
std::cout << "Welcome to the app!" << std::endl;
// Download config file if available
if (!context.application.files.empty()) {
client.download_file(
context.application.files[0].id,
true,
"config.json"
);
}
} else {
std::cout << "Please purchase a license" << std::endl;
}
} catch (const authgate::AuthenticationError& e) {
std::cerr << "Login failed - wrong credentials" << std::endl;
} catch (const authgate::AuthorizationError& e) {
std::cerr << "Access denied - inactive membership" << std::endl;
} catch (const authgate::AuthgateApiError& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}