Authentication
Configure comet-auth with social OAuth, D1/KV, sessions, and protected routes.
comet-auth adds authentication to Comet/Rocket applications on Cloudflare
Workers. It stores users, linked provider accounts, and sessions in D1, uses KV
for OAuth state/cache, and exposes Rocket guards for protected routes.
Bindings
Configure one D1 database and one KV namespace in wrangler.jsonc:
{
"d1_databases": [{
"binding": "DB",
"database_name": "my-app",
"database_id": "...",
"migrations_dir": "migrations"
}],
"kv_namespaces": [{
"binding": "AUTH_KV",
"id": "..."
}]
}Add the auth migration:
comet auth init --db-binding DB --kv-binding AUTH_KV --with-rbac
npx wrangler d1 migrations apply DB --local
npx wrangler d1 migrations apply DB --remoteRocket Mount
pub struct DB;
impl comet::cloudflare::BindingName for DB {
const NAME: &'static str = "DB";
}
pub struct AuthKv;
impl comet::cloudflare::BindingName for AuthKv {
const NAME: &'static str = "AUTH_KV";
}
let auth_config = comet_auth::AuthConfig::from_env()
.base_url("https://example.com")
.provider(
comet_auth::providers::Google::from_env()
.web_client_id_env("GOOGLE_WEB_CLIENT_ID")
.web_client_secret_env("GOOGLE_WEB_CLIENT_SECRET")
.native_client_id_env("GOOGLE_IOS_CLIENT_ID")
.native_client_id_env("GOOGLE_ANDROID_CLIENT_ID"),
)
.provider(
comet_auth::providers::Apple::from_env()
.service_id_env("APPLE_SERVICE_ID")
.team_id_env("APPLE_TEAM_ID")
.key_id_env("APPLE_KEY_ID")
.private_key_pkcs8_pem_env("APPLE_PRIVATE_KEY_PKCS8_PEM")
.native_audience_env("APPLE_IOS_BUNDLE_ID"),
)
.provider(
comet_auth::providers::GitHub::from_env()
.client_id_env("GITHUB_CLIENT_ID")
.client_secret_env("GITHUB_CLIENT_SECRET"),
);
rocket::build()
.attach(comet_auth::Auth::<DB, AuthKv>::fairing(auth_config))
.mount("/auth", comet_auth::routes::<DB, AuthKv>());Protected Routes
Put #[comet_auth::requires_auth] above the Rocket route attribute:
#[comet_auth::requires_auth]
#[rocket::get("/private/me")]
async fn private_me(session: comet_auth::AuthSession) -> &'static str {
"authenticated"
}For routes that can handle anonymous visitors:
#[comet_auth::requires_auth(optional)]
#[rocket::get("/maybe")]
async fn maybe(session: comet_auth::OptionalAuthSession) -> &'static str {
if session.0.is_some() { "signed in" } else { "anonymous" }
}Authorization policies are enforced with D1-backed RBAC:
#[comet_auth::requires_auth(role = "admin")]
#[rocket::get("/admin")]
async fn admin() -> &'static str {
"admin"
}
#[comet_auth::requires_auth(permission = "boards:write")]
#[rocket::post("/boards")]
async fn create_board() -> &'static str {
"created"
}Top-level policies are all by default. Use any(...) when one matching
claim is enough, and resource = "..." for static resource-scoped checks:
#[comet_auth::requires_auth(any(role = "admin", permission = "tasks:review"), resource = "demo")]
#[rocket::get("/private/reviewer")]
async fn reviewer() -> &'static str {
"reviewer"
}scope = "..." works as a permission alias. Missing sessions return
401 Unauthorized; authenticated sessions without the required role,
permission, or scope return 403 Forbidden.
Authorization claims are loaded from D1 and cached in KV for 60 seconds by default. Tune or disable this with:
comet_auth::AuthConfig::from_env()
.authorization_claims_cache_ttl_seconds(0);To create RBAC tables when initializing auth:
comet auth init --with-rbacProvider Secrets
Set secrets with wrangler secret put <NAME>.
Common:
COMET_AUTH_BASE_URL: public origin used for OAuth callbacks.COMET_AUTH_TOKEN_PEPPER: extra secret material mixed into session token hashes.
Google:
GOOGLE_WEB_CLIENT_IDGOOGLE_WEB_CLIENT_SECRETGOOGLE_IOS_CLIENT_ID, optional native login audienceGOOGLE_ANDROID_CLIENT_ID, optional native login audience
Apple:
APPLE_SERVICE_IDAPPLE_TEAM_IDAPPLE_KEY_IDAPPLE_PRIVATE_KEY_PKCS8_PEMAPPLE_IOS_BUNDLE_ID, optional native login audience
GitHub:
GITHUB_CLIENT_IDGITHUB_CLIENT_SECRET
Redirect URIs
Register these callbacks in each provider dashboard:
- Google:
<COMET_AUTH_BASE_URL>/auth/google/callback - Apple:
<COMET_AUTH_BASE_URL>/auth/apple/callback - GitHub:
<COMET_AUTH_BASE_URL>/auth/github/callback
Native Login
Native clients should use the provider's official SDK to obtain an identity token, then send it to Comet:
curl -X POST https://example.com/auth/native/google \
-H 'content-type: application/json' \
-d '{"id_token":"...","nonce":"..."}'Apple uses the same shape at /auth/native/apple.
Do not use an embedded WebView for Google login. For browser login from a
mobile app, use the secure system browser, such as ASWebAuthenticationSession,
SFSafariViewController, or Chrome Custom Tabs.