huudis
Docs · v0.2.0

Ship identity in an afternoon.

Copy-paste examples in Node and cURL. Every endpoint uses the same wire format whether you sign in as a human, a service account, or a device.

#Quickstart

Every Huudis tenant gets an OIDC issuer and an API origin. Sign users up, get an access token, verify it on your backend. That’s it.

1Create an account
2Install the SDK
npm install @forjio/sdk
3Verify an access token
server.ts
import { verifyAccessToken } from '@forjio/sdk';

app.get('/me', async (req, res) => {
  const claims = await verifyAccessToken(req.headers.authorization);
  res.json({ userId: claims.sub, email: claims.email });
});

#OIDC integration

Huudis is a full OpenID Provider. Point your client at the discovery document and everything else falls out of the spec.

Discovery
https://huudis.com/.well-known/openid-configuration
JWKS
https://huudis.com/.well-known/jwks.json
Authorize
/api/v1/oidc/authorize?response_type=code&client_id=…&redirect_uri=…&scope=openid%20profile%20email&code_challenge=…&code_challenge_method=S256&state=…
Token
POST /api/v1/oidc/tokenGrants: authorization_code, refresh_token, urn:ietf:params:oauth:grant-type:device_code.
Userinfo
GET /api/v1/oidc/userinfo
Signing
ES256Keys published via JWKS and rotated every 90 days.

#CLI

The huudis CLI logs in over RFC 8628 device flow, then lets you drive IAM, audit, and sessions from your terminal.

zsh
$ npm install -g @forjio/huudis-cli
$ huudis auth login
→ Visit https://huudis.com/device and enter code A3F7-9C2D
Signed in as you@yourcompany.com
$ huudis iam list-policies
$ huudis iam list-groups
$ huudis iam create-access-key --principal-type user --principal-id usr_abc
$ huudis account sessions list
$ huudis audit list --event iam.access_key.create --limit 20

#IAM policies

AWS-IAM-style JSON policies. Effect, Action, Resource, Condition, NotAction, NotResource are all supported. 28 canned policies ship out of the box — Admin / Developer / ReadOnly / Billing crossed with each Forjio service.

ripllo-publisher-policy.json
{
  "Version": "2026-04-18",
  "Statement": [
    {
      "Sid": "PublishOwnCampaigns",
      "Effect": "Allow",
      "Action": [
        "ripllo:ReadCampaign",
        "ripllo:PublishCampaign"
      ],
      "Resource": "forjio:ripllo::acc_abc:campaign/*",
      "Condition": {
        "Bool": { "forjio:MfaPresent": true }
      }
    }
  ]
}

#Access keys + HMAC

AKIA* access keys are long-term; ASIA* keys come from assume-role and expire in an hour. Both sign requests with a plain HMAC-SHA256 header — simpler than AWS SigV4, sufficient for M2.

signed-request.http
# StringToSign — one line per component, newline-joined:
#   HTTP-METHOD
#   /path?with=query
#   X-Huudis-Date header value (ISO-8601, e.g. 2026-04-18T09:30:00.000Z)
#   sha256(request body bytes).hex

# Signature = hex(HMAC-SHA256(secret_access_key, StringToSign))

Authorization: Huudis-HMAC-SHA256 Credential=AKIA0123456789ABCDEF, Signature=<hex>
X-Huudis-Date: 2026-04-18T09:30:00.000Z

# Clock skew tolerance: ±5 minutes.
# Compare is constant-time.

#Webhooks

Coming in M4

Signed auth.* and iam.* events delivered to your HTTPS endpoint with exponential-backoff retries. Today, query huudis audit list from the CLI in the meantime.