Python SDK API Reference

Complete API reference for the Hawcx Python SDK

Python SDK API Reference

HawcxOAuth

Initialize the OAuth client and exchange codes for verified claims.

from hawcx_oauth_client import HawcxOAuth
import os

oauth = HawcxOAuth(
    config_id=os.getenv('HAWCX_CONFIG_ID'),
    base_url=os.environ['HAWCX_BASE_URL'],  # from Admin Console
)

exchange_code(auth_code, code_verifier)

Exchange an authorization code for verified claims.

result = oauth.exchange_code(auth_code, code_verifier)
claims = result.claims

# claims['sub'] = user ID
# claims.get('email') = verified email (if present)

Returns:

  • result.id_token: raw JWT (do not use as access token)
  • result.claims: verified claims

verify_token(token)

Verify a JWT and return its claims.

claims = oauth.verify_token(id_token)

Step-Up Client (Management API)

StepUpClient is the entry point for the management / step-up API (/v1/management/*) — start_token, consume_receipt, and a generic management_request escape hatch.

Recommended: reuse your OIDC signing key

with_private_key_jwt (Path A) is the recommended way to authenticate management API calls. It reuses the same Ed25519 private_key_jwt signing key you already registered for OIDC login — one key instead of the legacy four-key ECIES blob — and is fully standards-based (RFC 7523).

Prerequisite: enable jwt on the Management API Authentication card

Before management calls can authenticate with private_key_jwt, enable it for the project in the Admin Console → Project Settings → Management API Authentication:

  • Migrating — accepts both the legacy ECIES path and signed private_key_jwt. Use this during rollout so existing and new callers coexist.
  • Signed tokensprivate_key_jwt only (after every caller has migrated).

If the project is left on Legacy (ECIES only), private_key_jwt management calls are rejected with management_auth_mode_not_allowed (HTTP 401) — even with a correctly registered key. Note: regenerating an ECIES secret-key blob resets the project to Legacy, so set this after any blob regeneration.

Mints a short-lived per-request EdDSA Bearer JWT (iss = sub = client_id, aud = the full endpoint URL, ~60s lifetime, random jti, and a body_sha256 claim that binds the JWT to the exact request body bytes). Routing uses the X-Config-Id header.

import os
from hawcx_oauth_client import StepUpClient

client = StepUpClient.with_private_key_jwt(
    oidc_signing_key=os.environ["HAWCX_OIDC_PRIVATE_KEY_PEM"],  # Ed25519 PEM or bytes
    kid=os.environ["HAWCX_PRIVATE_KEY_KID"],  # key id registered in the Hawcx Admin Console
    client_id=os.environ["HAWCX_CLIENT_ID"],
    base_url="https://api.hawcx.com",
    config_id=os.environ["HAWCX_CONFIG_ID"],
)

# Begin a step-up flow (purposes: "change_mfa_method", "change_phone_number")
result = client.start_token(
    user_id="[email protected]",
    purpose="change_mfa_method",
    new_mfa_method="email_otp",
)

# Finalize after the user completes the MFA challenge. The receipt is returned
# to your frontend by the Hawcx SDK once the challenge succeeds; forward it to
# your backend and pass it here.
receipt = "receipt-from-frontend-after-mfa"
client.consume_receipt(receipt=receipt)

# Generic call for any /v1/management/* endpoint
client.management_request(
    endpoint="/v1/management/users/mfa-enforcement",
    payload={"userid": "[email protected]"},
)

Responses carry an X-Response-Signature JWS (ES256) that you may verify against the OIDC JWKS you already trust.

StepUpClient.from_secret_key() (legacy, deprecated)

Legacy ECIES path — deprecated

from_secret_key and from_keys use the proprietary ECIES credential blob (hwx_sk_v1_…). They are deprecated but still functional (a DeprecationWarning is emitted) and will only be removed in a future major release. Migrate to with_private_key_jwt at your leisure.

from hawcx_oauth_client import StepUpClient

client = StepUpClient.from_secret_key(   # DeprecationWarning is emitted
    secret_key="hwx_sk_v1_...",
    base_url="https://api.hawcx.com",
    api_key="your-config-id",
    tenant_header_name="X-Config-Id",
    tenant_header_value="your-config-id",
)

client.start_token(user_id="[email protected]", purpose="change_mfa_method")

Delegation Client

Use the delegation client for backend-driven MFA setup and user/device management.

HawcxDelegationClient.from_keys()

from hawcx_oauth_client.delegation import HawcxDelegationClient
import os

client = HawcxDelegationClient.from_keys(
    sp_signing_key=os.getenv('SP_ED25519_PRIVATE_KEY_PEM'),
    sp_encryption_key=os.getenv('SP_X25519_PRIVATE_KEY_PEM'),
    idp_verify_key=os.getenv('IDP_ED25519_PUBLIC_KEY_PEM'),
    idp_encryption_key=os.getenv('IDP_X25519_PUBLIC_KEY_PEM'),
    base_url=os.environ['HAWCX_BASE_URL'],
    sp_id=os.getenv('OAUTH_CLIENT_ID')
)

MFA

from hawcx_oauth_client.delegation import MfaMethod

result = client.initiate_mfa_change(
    userid='[email protected]',
    mfa_method=MfaMethod.SMS,
    phone_number='+15551234567'
)

client.verify_mfa_change(
    userid='[email protected]',
    session_id=result['session_id'],
    otp='123456'
)

Users

creds = client.get_user_credentials('[email protected]')