gleamunison/auth

Typed request identity, scopes, and bind policy.

Data over dispatch: routes map to scopes, identities carry scopes, and authorization is a pure decision. The Erlang HTTP/sync servers call required_scope/1, authorize_scopes/2 and bind_decision/1; they do not re-implement policy.

Types

pub type BindDecision {
  Allow
  Refuse(reason: String)
}

Constructors

  • Allow
  • Refuse(reason: String)
pub type BindInput {
  BindInput(
    address: String,
    profile: String,
    http_token_present: Bool,
    sync_token_present: Bool,
  )
}

Constructors

  • BindInput(
      address: String,
      profile: String,
      http_token_present: Bool,
      sync_token_present: Bool,
    )
pub type Identity {
  Anonymous
  LocalPeer
  Bearer(token_hash: String, scopes: List(Scope))
  ProxyPrincipal(name: String, scopes: List(Scope))
}

Constructors

  • Anonymous
  • LocalPeer
  • Bearer(token_hash: String, scopes: List(Scope))
  • ProxyPrincipal(name: String, scopes: List(Scope))
pub type Scope {
  Public
  DataRead
  DataWrite
  Admin
}

Constructors

  • Public
  • DataRead
  • DataWrite
  • Admin

Values

pub fn authorize_scopes(
  scopes: List(Scope),
  path: String,
) -> Result(Nil, String)

The whole authorization decision, over scopes rather than an identity. Transport adapters resolve a credential to its scopes and ask this; they do not decide policy themselves.

pub fn bind_decision(input: BindInput) -> BindDecision

Non-loopback binding is a refusal boundary, not a configuration option. Loopback binds always allow. Remote binds require the authenticated-remote profile and an authentication contract (HTTP token for the reverse proxy; direct TLS termination is intentionally not implemented in this runtime).

pub fn required_scope(path: String) -> Scope
✨ Search Document