Files
mcias/clients/python
Kyle Isom 8545473703 Fix SEC-01: require password for TOTP enroll
- REST handleTOTPEnroll now requires password field in request body
- gRPC EnrollTOTP updated with password field in proto message
- Both handlers check lockout status and record failures on bad password
- Updated Go, Python, and Rust client libraries to pass password
- Updated OpenAPI specs with new requestBody schema
- Added TestTOTPEnrollRequiresPassword with no-password, wrong-password,
  and correct-password sub-tests

Security: TOTP enrollment now requires the current password to prevent
session-theft escalation to persistent account takeover. Lockout and
failure recording use the same Argon2id constant-time path as login.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 00:48:31 -07:00
..

mcias-client (Python)

Python client library for the MCIAS identity and access management API.

Requirements

  • Python 3.11+
  • httpx >= 0.27

Installation

pip install .
# or in development mode:
pip install -e ".[dev]"

Quick Start

from mcias_client import Client

# Connect to the MCIAS server.
with Client("https://auth.example.com") as client:
    # Authenticate.
    token, expires_at = client.login("alice", "s3cret")
    print(f"token expires at {expires_at}")

    # The token is stored in the client automatically.
    accounts = client.list_accounts()

    # Revoke the token when done (also called automatically on context exit).
    client.logout()

Custom CA Certificate

client = Client(
    "https://auth.example.com",
    ca_cert_path="/etc/mcias/ca.pem",
)

Error Handling

All methods raise typed exceptions on error:

from mcias_client import (
    MciasAuthError,
    MciasForbiddenError,
    MciasNotFoundError,
    MciasInputError,
    MciasConflictError,
    MciasServerError,
)

try:
    client.login("alice", "wrongpass")
except MciasAuthError as e:
    print(f"auth failed ({e.status_code}): {e.message}")
except MciasForbiddenError as e:
    print(f"forbidden: {e.message}")
except MciasNotFoundError as e:
    print(f"not found: {e.message}")
except MciasInputError as e:
    print(f"bad input: {e.message}")
except MciasConflictError as e:
    print(f"conflict: {e.message}")
except MciasServerError as e:
    print(f"server error {e.status_code}: {e.message}")

All exception types are subclasses of MciasError, which has attributes:

  • status_code: int — HTTP status code
  • message: str — server error message

Thread Safety

Client is not thread-safe. Each thread should use its own Client instance.

Running Tests

pip install -e ".[dev]"
pytest tests/ -q
mypy mcias_client/ tests/
ruff check mcias_client/ tests/