Files
Kyle Isom 0c441f5c4f Implement Phase 9: client libraries (Go, Rust, Lisp, Python)
- clients/README.md: canonical API surface and error type reference
- clients/testdata/: shared JSON response fixtures
- clients/go/: mciasgoclient package; net/http + TLS 1.2+; sync.RWMutex
  token state; DisallowUnknownFields on all decoders; 25 tests pass
- clients/rust/: async mcias-client crate; reqwest+rustls (no OpenSSL);
  thiserror MciasError enum; Arc<RwLock> token state; 22+1 tests pass;
  cargo clippy -D warnings clean
- clients/lisp/: ASDF mcias-client; dexador HTTP, yason JSON; mcias-error
  condition hierarchy; Hunchentoot mock-dispatcher; 37 fiveam checks pass
  on SBCL 2.6.1; yason boolean normalisation in validate-token
- clients/python/: mcias_client package (Python 3.11+); httpx sync;
  py.typed; dataclasses; 32 pytest tests; mypy --strict + ruff clean
- test/mock/mockserver.go: in-memory mock server for Go client tests
- ARCHITECTURE.md §19: updated per-language notes to match implementation
- PROGRESS.md: Phase 9 marked complete
- .gitignore: exclude clients/rust/target/, python .venv, .pytest_cache,
  .fasl files
Security: token never logged or exposed in error messages in any library;
TLS enforced in all four languages; token stored under lock/mutex/RwLock
2026-03-11 16:38:32 -07:00
..

mcias-client (Go)

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

Requirements

  • Go 1.21+

Installation

go get git.wntrmute.dev/kyle/mcias/clients/go

Quick Start

import mciasgoclient "git.wntrmute.dev/kyle/mcias/clients/go"

// Connect to the MCIAS server.
client, err := mciasgoclient.New("https://auth.example.com", mciasgoclient.Options{})
if err != nil {
    log.Fatal(err)
}

// Authenticate.
token, expiresAt, err := client.Login("alice", "s3cret", "")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("token expires at %s\n", expiresAt)

// The token is stored in the client automatically.
// Call authenticated endpoints...
accounts, err := client.ListAccounts()

// Revoke the token when done.
if err := client.Logout(); err != nil {
    log.Fatal(err)
}

Custom CA Certificate

client, err := mciasgoclient.New("https://auth.example.com", mciasgoclient.Options{
    CACertPath: "/etc/mcias/ca.pem",
})

Error Handling

All methods return typed errors:

_, _, err := client.Login("alice", "wrongpass", "")
switch {
case errors.Is(err, new(mciasgoclient.MciasAuthError)):
    // 401 — wrong credentials or token invalid
case errors.Is(err, new(mciasgoclient.MciasForbiddenError)):
    // 403 — insufficient role
case errors.Is(err, new(mciasgoclient.MciasNotFoundError)):
    // 404 — resource not found
case errors.Is(err, new(mciasgoclient.MciasInputError)):
    // 400 — malformed request
case errors.Is(err, new(mciasgoclient.MciasConflictError)):
    // 409 — conflict (e.g. duplicate username)
case errors.Is(err, new(mciasgoclient.MciasServerError)):
    // 5xx — unexpected server error
}

All error types embed MciasError which carries StatusCode int and Message string.

Thread Safety

Client is safe for concurrent use from multiple goroutines. The internal token is protected by sync.RWMutex.

Running Tests

go test -race ./...