iam

package
v1.801.471 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 5, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package iam is the admin cockpit's typed reader for the Hanzo IAM management surface (/v1/iam/ native routes). IAM runs as its own deployment (not fused into this binary), so these are HTTP calls, not Go method dispatch. Every call REPLAYS THE CALLER'S OWN credential (session cookie + Authorization), so IAM authorizes the read as the same principal the gateway already validated as a SuperAdmin. admin adds NO service credential of its own here: it never widens what the caller could read directly, and IAM's own IsSuperAdmin gate stays the second line of defense.

The reads split two orthogonal ways: TYPED domain reads the cockpit folds into its own rows — Orgs/Users (paginated lists), Org/User (one row), SetUser (the one write) — and a generic verbatim List the cockpit forwards field-for-field (roles, applications, audit records). An unwired IAM (no base) is not Ready and every read reports the honest not-configured error.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client reads the IAM management surface (/v1/iam/ native routes) on behalf of a verified SuperAdmin caller.

func New

func New(base string) *Client

New builds an IAM client for base (empty base → not Ready).

func (*Client) List

func (c *Client) List(ctx context.Context, cr Creds, path string, q url.Values) (List, error)

List calls an IAM get-* endpoint and returns the raw data array + data2 total — the verbatim-forward primitive (roles, applications, audit records reach the operator field-for-field). A non-ok envelope is an error (surfaced honestly to the operator).

func (*Client) Org

func (c *Client) Org(ctx context.Context, cr Creds, id string) (Org, error)

Org fetches ONE organization row (GET /v1/iam/organizations/get?owner=&name=) as the typed Org subset the scoped read panels fold over. Replays the caller's own credential, so IAM authorizes the read as the same validated principal — a non-super caller can only ever read their OWN org this way (the second line of the tenant-scope defense). Best-effort by design: the scoped-orgs fan-in tolerates an error and falls back to a name-only row.

func (*Client) Orgs

func (c *Client) Orgs(ctx context.Context, cr Creds, q url.Values) (List, error)

Orgs lists organizations (GET /v1/iam/organizations).

func (*Client) Ready

func (c *Client) Ready() bool

Ready reports whether an IAM endpoint is wired on this deployment.

func (*Client) SetUser

func (c *Client) SetUser(ctx context.Context, cr Creds, id string, user map[string]any) error

SetUser writes a full user object back (POST /v1/iam/update-user?id=owner/name). The caller's replayed credential is a VALIDATED SuperAdmin, whom IAM's CheckPermissionForUpdateUser admits to set privileged fields (isForbidden) on any user — a tenant/org-admin is refused by IAM itself, so this can never be abused to suspend across a boundary the caller couldn't already cross. admin adds no service credential of its own; IAM re-checks IsSuperAdmin.

func (*Client) User

func (c *Client) User(ctx context.Context, cr Creds, id string) (map[string]any, error)

User fetches ONE user as its FULL wire object (GET /v1/iam/users/get?owner=&name= ; was get-user?id= owner/name), preserving every field. The suspend/reactivate action reads the whole object, flips isForbidden, and writes it back — update-user REPLACES the row, so operating on the full object (not a typed subset) is what keeps every other field intact. Replays the caller's own credential, so IAM authorizes the read as the same validated SuperAdmin.

func (*Client) Users

func (c *Client) Users(ctx context.Context, cr Creds, q url.Values) (List, error)

Users lists users (GET /v1/iam/users).

type Creds

type Creds struct {
	Cookie string
	Auth   string
}

Creds is the caller's replayed authorization context: the raw Cookie header and Authorization bearer captured off the inbound request. IAM authenticates exactly as it does for the browser (credentials: 'include').

type List

type List struct {
	Rows  json.RawMessage
	Total int
}

List is a decoded paginated read: the raw rows and the backend total.

type Org

type Org struct {
	Owner       string `json:"owner"`
	Name        string `json:"name"`
	DisplayName string `json:"displayName"`
	CreatedTime string `json:"createdTime"`
}

Org is the IAM Organization subset the aggregators fold over.

type User

type User struct {
	Owner          string `json:"owner"`
	Name           string `json:"name"`
	Email          string `json:"email"`
	DisplayName    string `json:"displayName"`
	Tag            string `json:"tag"`
	CreatedTime    string `json:"createdTime"`
	LastSigninTime string `json:"lastSigninTime"`
	IsAdmin        bool   `json:"isAdmin"`
	IsForbidden    bool   `json:"isForbidden"`
	AccessKey      string `json:"accessKey"`
}

User is the IAM User subset mapped into OperatorUser. AccessKey is decoded ONLY to derive API-key PRESENCE (hasApiKey) for the customer detail — its VALUE is never surfaced in any admin response (the key is a credential, not a display field), so no secret leaves this binary.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL