Arcadic.Security (Arcadic v0.7.0)

Copy Markdown View Source

Server security & auth admin: session login/logout, active sessions, and user/group/API-token management — over ArcadeDB's HTTP admin surface. Reads (users/groups/api_tokens/sessions) use the read-only REST endpoints; mutations (create_user/drop_user) use server commands (the REST paths are read-only — POST /server/users → 400). Tenant-blind.

create_user/2 is the one place a caller VALUE (the password) reaches a statement: server commands cannot bind params (probed), so the user spec is Jason.encoded into create user <json> — the JSON backslash-escaping round-trips exactly against ArcadeDB's create user lexer (live-verified). The encode uses the NON-raising Jason.encode/1: a non-UTF8 binary password passes the is_binary guard but would make Jason.encode! raise a Jason.EncodeError that renders the raw bytes, so an unencodable spec is rejected value-free as {:error, :invalid_user_spec} (the Jason error, which holds the bytes, is discarded) before any wire call. The password NEVER enters an error, log, or telemetry line (the server error is name-only; arcadic only ever emits valid JSON; Arcadic.Error quarantines detail; the admin span is value-free).

Summary

Functions

List server API tokens (GET /api/v1/server/api-tokens).

Create a server user from %{name:, password:, databases: %{db => [roles]}} (databases optional). name is Identifier-validated; the spec is Jason.encoded into the command. The password is never echoed (Rule 3): an unencodable spec (e.g. a non-UTF8 binary) is rejected value-free as {:error, :invalid_user_spec}. Returns :ok or a typed error.

Drop a server user. Validates name.

The server security-groups map (GET /api/v1/server/groups).

Mint a session token from the conn's credentials (POST /api/v1/login).

Revoke the current session (POST /api/v1/logout).

List active sessions (GET /api/v1/sessions). Rows carry caller-owned tokens — do not log them.

List server users (GET /api/v1/server/users).

Functions

api_tokens(conn)

@spec api_tokens(Arcadic.Conn.t()) :: {:ok, [map()]} | {:error, Exception.t()}

List server API tokens (GET /api/v1/server/api-tokens).

api_tokens!(conn)

@spec api_tokens!(Arcadic.Conn.t()) :: [map()]

create_user(conn, spec)

@spec create_user(Arcadic.Conn.t(), map()) :: :ok | {:error, atom() | Exception.t()}

Create a server user from %{name:, password:, databases: %{db => [roles]}} (databases optional). name is Identifier-validated; the spec is Jason.encoded into the command. The password is never echoed (Rule 3): an unencodable spec (e.g. a non-UTF8 binary) is rejected value-free as {:error, :invalid_user_spec}. Returns :ok or a typed error.

create_user!(conn, spec)

@spec create_user!(Arcadic.Conn.t(), map()) :: :ok

drop_user(conn, name)

@spec drop_user(Arcadic.Conn.t(), String.t()) ::
  :ok | {:error, atom() | Exception.t()}

Drop a server user. Validates name.

drop_user!(conn, name)

@spec drop_user!(Arcadic.Conn.t(), String.t()) :: :ok

groups(conn)

@spec groups(Arcadic.Conn.t()) :: {:ok, map()} | {:error, Exception.t()}

The server security-groups map (GET /api/v1/server/groups).

groups!(conn)

@spec groups!(Arcadic.Conn.t()) :: map()

login(conn)

@spec login(Arcadic.Conn.t()) :: {:ok, String.t()} | {:error, Exception.t()}

Mint a session token from the conn's credentials (POST /api/v1/login).

login!(conn)

@spec login!(Arcadic.Conn.t()) :: String.t()

logout(conn)

@spec logout(Arcadic.Conn.t()) :: :ok | {:error, Exception.t()}

Revoke the current session (POST /api/v1/logout).

logout!(conn)

@spec logout!(Arcadic.Conn.t()) :: :ok

sessions(conn)

@spec sessions(Arcadic.Conn.t()) :: {:ok, [map()]} | {:error, Exception.t()}

List active sessions (GET /api/v1/sessions). Rows carry caller-owned tokens — do not log them.

sessions!(conn)

@spec sessions!(Arcadic.Conn.t()) :: [map()]

users(conn)

@spec users(Arcadic.Conn.t()) :: {:ok, [map()]} | {:error, Exception.t()}

List server users (GET /api/v1/server/users).

users!(conn)

@spec users!(Arcadic.Conn.t()) :: [map()]