- 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>
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 codemessage: 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/