AXIAM C++ SDK 1.0.0-alpha8
Authentication, authorization, JWKS & route guards (REST + mTLS)
Loading...
Searching...
No Matches
authenticator.hpp
Go to the documentation of this file.
1// §10 safe-by-default request authenticator.
2//
3// This is THE entry point for turning an inbound credential into an AxiamUser.
4//
5// <axiam/jwks.hpp> ships a deliberately minimal primitive
6// (JwksVerifier::verify_signature_only_unchecked) that proves a token was signed
7// by the org's Ed25519 key and stops there. A valid signature is not an
8// authentication decision: the JWKS endpoint is org-wide, so a signature alone
9// says nothing about whether the token has expired, has started being valid, or
10// was minted for THIS tenant. Wiring the raw primitive into a route guard
11// therefore accepts expired and cross-tenant tokens.
12//
13// TokenAuthenticator closes that gap. Every successful authenticate() has
14// established, in order:
15//
16// 1. the compact JWS is well formed and `alg` is EdDSA;
17// 2. the signature verifies against the cached JWKS;
18// 3. `exp` is present, is an integer, and has not passed (allowing a small,
19// named clock skew);
20// 4. `nbf`, when present, is an integer and has arrived (same skew);
21// 5. `tenant_id` is present, is a non-empty string, and equals the tenant this
22// authenticator was configured with;
23// 6. optionally, `iss` / `aud` match configured expectations.
24//
25// Anything missing, malformed or mismatched is a failure — the authenticator
26// fails closed and never returns a partially-checked identity.
27#pragma once
28
29#include <chrono>
30#include <cstdint>
31#include <functional>
32#include <optional>
33#include <string>
34
35#include "axiam/client.hpp"
36#include "axiam/errors.hpp"
37#include "axiam/guard.hpp"
38#include "axiam/jwks.hpp"
39
40namespace axiam {
41
43using NowFn = std::function<std::int64_t()>;
44
55inline constexpr std::chrono::seconds kDefaultClockSkew{30};
56inline constexpr std::chrono::seconds kMaxClockSkew{60};
57
64 std::chrono::seconds clock_skew{kDefaultClockSkew};
65
67 std::optional<std::string> expected_issuer;
68
71 std::optional<std::string> expected_audience;
72
75};
76
82public:
90 AuthenticatorOptions options = {});
91
95 AxiamUser authenticate(const std::string& token) const;
96
98 std::optional<AxiamUser> try_authenticate(const std::string& token) const;
99
101 const std::string& expected_tenant_id() const noexcept { return tenant_id_; }
102
105 static std::optional<std::string> bearer_from_authorization(const std::string& header_value);
106
108 static std::optional<std::string> token_from_cookie_header(const std::string& cookie_header);
109
113 template <typename Request>
115 std::function<std::optional<std::string>(const Request&)> extract_token) const {
116 const TokenAuthenticator* self = this;
117 return [self, extract_token](const Request& req) -> std::optional<AxiamUser> {
118 auto token = extract_token(req);
119 if (!token.has_value()) return std::nullopt;
120 return self->try_authenticate(*token);
121 };
122 }
123
124private:
125 JwksVerifier* jwks_;
126 std::string tenant_id_;
127 AuthenticatorOptions options_;
128};
129
132inline TokenAuthenticator make_authenticator(Client& client, std::string expected_tenant_id,
133 AuthenticatorOptions options = {}) {
134 return TokenAuthenticator(client.jwks(), std::move(expected_tenant_id), std::move(options));
135}
136
137} // namespace axiam
std::function< std::optional< AxiamUser >(const Request &)> Authenticator
Definition guard.hpp:107
Definition client.hpp:24
JwksVerifier & jwks()
Shared JWKS verifier bound to this client's transport + base URL.
Definition jwks.hpp:43
Safe-by-default local verification of an AXIAM access token.
Definition authenticator.hpp:81
static std::optional< std::string > bearer_from_authorization(const std::string &header_value)
Extract a bearer token from an Authorization header value.
static std::optional< std::string > token_from_cookie_header(const std::string &cookie_header)
Extract the axiam_access token from a Cookie request header value.
std::optional< AxiamUser > try_authenticate(const std::string &token) const
Non-throwing twin, for wiring into AxiamGuard / framework adapters.
AxiamUser authenticate(const std::string &token) const
Verify token and build the authenticated identity.
const std::string & expected_tenant_id() const noexcept
The tenant every token is bound to.
Definition authenticator.hpp:101
TokenAuthenticator(JwksVerifier &jwks, std::string expected_tenant_id, AuthenticatorOptions options={})
AxiamGuard< Request >::Authenticator guard_authenticator(std::function< std::optional< std::string >(const Request &)> extract_token) const
Build a §10 guard authenticator: given a way to pull the raw credential out of a framework request,...
Definition authenticator.hpp:114
Definition authenticator.hpp:40
constexpr std::chrono::seconds kMaxClockSkew
Definition authenticator.hpp:56
TokenAuthenticator make_authenticator(Client &client, std::string expected_tenant_id, AuthenticatorOptions options={})
Convenience factory: an authenticator bound to a client's JWKS verifier.
Definition authenticator.hpp:132
constexpr std::chrono::seconds kDefaultClockSkew
CONTRACT §10.1 rule 7 — the leeway applied to exp and nbf must be a named, documented,...
Definition authenticator.hpp:55
std::function< std::int64_t()> NowFn
Clock seam: returns the current time as unix seconds. Injected in tests.
Definition authenticator.hpp:43
Tuning for TokenAuthenticator. The defaults are the safe ones.
Definition authenticator.hpp:59
std::chrono::seconds clock_skew
Tolerance applied to exp and nbf for small clock differences between this resource server and the AXI...
Definition authenticator.hpp:64
std::optional< std::string > expected_issuer
When set, the iss claim must be present and equal to this value.
Definition authenticator.hpp:67
std::optional< std::string > expected_audience
When set, the aud claim must be present and must contain this value (aud may be a string or an array ...
Definition authenticator.hpp:71
NowFn now
Time source. Empty => the system clock.
Definition authenticator.hpp:74
Authenticated identity injected by the §10 guard into the request context.
Definition guard.hpp:27