eficens-iam-sdk
v0.4.2
Published
JavaScript/TypeScript SDK for the Eficens IAM service
Maintainers
Readme
eficens-iam-sdk (JavaScript / TypeScript)
Client SDKs for the Eficens IAM API:
- App SDK (
IamClient) — end-user signup/login, token refresh, introspect, authorization checks - Admin SDK (
IamAdminClient) — tenant/project management: roles, policies, vocabulary, principals, native users
Package: npmjs.com/package/eficens-iam-sdk
Install
npm install eficens-iam-sdkApp SDK vs Admin SDK
| | App (IamClient) | Admin (IamAdminClient) |
|--|-------------------|--------------------------|
| Auth | Project API key + end-user access token | Tenant-admin / platform-admin JWT |
| Login | POST /auth/token | POST /admin/login |
| Use for | Runtime authn/authz in your application | Provisioning and RBAC management |
| Credentials | Keep API key on a trusted backend | Keep admin password on a trusted backend — never in a browser |
Recommended flow
- In the IAM Console: create a tenant (or sign up as owner), create a project, copy the API key, enable native (or Cognito/Clerk) auth.
- From a trusted backend, use Admin SDK to create resources/actions, policies, roles, and assign roles to principals.
- End users self-register via App SDK
signupor hosted auth pages. - Your app runtime uses App SDK
login+check/batchCheck.
Tenant creation via API remains platform-admin only (POST /tenants). Self-service owners create their first tenant through console signup.
Prerequisites (App SDK)
From the IAM Console:
- Create a project and copy the API key (shown once; rotate later if needed).
- Configure Auth Settings (
native,cognito, orclerk). - Define resources/actions, roles, and policies (console or Admin SDK).
You need:
| Value | Example |
|-------|---------|
| API base URL | https://api-iam.eficensittest.com/v1 |
| Project ID | UUID from the console |
| API key | iam_… (server-side only — never ship in a public frontend) |
Quick start (App SDK)
import { IamClient, IamError } from "eficens-iam-sdk";
const iam = new IamClient({
baseUrl: "https://api-iam.eficensittest.com/v1",
projectId: process.env.IAM_PROJECT_ID!,
apiKey: process.env.IAM_API_KEY!,
});
const tokens = await iam.login("[email protected]", "secret");
const profile = await iam.introspect(tokens.access_token);
const allowed = await iam.check("todo.tasks.create", tokens.access_token);Quick start (Admin SDK)
import { IamAdminClient, IamError } from "eficens-iam-sdk";
const admin = new IamAdminClient({
baseUrl: "https://api-iam.eficensittest.com/v1",
});
await admin.login("[email protected]", "admin-password");
await admin.createResource(tenantId, projectId, "tasks");
await admin.createAction(tenantId, projectId, "create", { resource: "tasks" });
await admin.createPolicy(tenantId, projectId, "tasks-writer");
await admin.addPolicyPermission(tenantId, projectId, "tasks-writer", {
resource: "todo.tasks",
action: "create",
});
await admin.createRole(tenantId, projectId, "editor");
await admin.setRolePolicies(tenantId, projectId, "editor", ["tasks-writer"]);
await admin.replacePrincipalRoles(tenantId, projectId, principalId, ["editor"]);App constructor options
new IamClient({
baseUrl: string; // IAM API root including /v1
projectId: string; // Project UUID
apiKey?: string; // Required for introspect / check / batchCheck
fetchImpl?: typeof fetch; // Optional custom fetch (tests, polyfills)
});Admin constructor options
new IamAdminClient({
baseUrl: string; // IAM API root including /v1
fetchImpl?: typeof fetch;
});
// Then await admin.login(email, password) or admin.setToken(jwt)Headers
App SDK
| Header | When |
|--------|------|
| X-Api-Key | introspect, check, batchCheck |
| Authorization: Bearer <access_token> | introspect, check, batchCheck |
| X-Project-Id | check, batchCheck |
Login / refresh / ID-token exchange / signup / password helpers do not require the API key.
Admin SDK
| Header | When |
|--------|------|
| Authorization: Bearer <admin_token> | All management calls after login / setToken |
Authentication (App SDK)
Native signup
Creates a project native user and sends a verification email. Password min length is 12.
await iam.signup("[email protected]", "long-enough-password");
await iam.verifyEmail(tokenFromEmail);
// or
await iam.resendVerification("[email protected]");Native users must verify email before login succeeds.
Native password login
const tokens = await iam.login(email, password);
// { access_token, refresh_token, token_type }Access tokens expire (default 15 minutes). Store the refresh token securely and refresh before expiry.
Refresh
const refreshed = await iam.refresh(tokens.refresh_token);Forgot / reset password
await iam.forgotPassword("[email protected]");
await iam.resetPassword(tokenFromEmail, "new-long-password");Cognito / OIDC ID token exchange
After the user signs in with Cognito (or another OIDC IdP configured on the project):
const tokens = await iam.exchangeIdToken(idToken);Introspect
const profile = await iam.introspect(tokens.access_token);
// active, principal_id, tenant_id, project_id, email, roles, permissionsAuthorization (App SDK)
Permission strings follow {projectSlug}.{resource}.{action} (e.g. todo.tasks.create).
Single check
const allowed = await iam.check("todo.tasks.create", tokens.access_token);
if (!allowed) throw new Error("Forbidden");Batch check
const { results } = await iam.batchCheck(
[
{ permission: "todo.tasks.read" },
{ permission: "todo.tasks.delete" },
// or split form:
// { resource: "todo.tasks", action: "read" },
],
tokens.access_token,
);Admin management APIs
After await admin.login(...):
| Area | Methods |
|------|---------|
| Session | login, setToken, me |
| Tenants / projects | listTenants, listProjects, getAuthConfig, updateAuthConfig |
| Vocabulary | listResources, createResource, updateResource, deleteResource, listActions (optional resource filter), createAction (requires resource / resourceId), updateAction, deleteAction |
| Roles | listRoles, createRole, getRole, deleteRole, setRolePolicies, addRolePolicies, removeRolePolicy |
| Policies | listPolicies, getPolicy, createPolicy, updatePolicy (description and/or full permissions replace), deletePolicy, addPolicyPermission, removePolicyPermission, setPolicyPermissions |
| Principals | listPrincipals, getPrincipal, getPrincipalRoles, getPrincipalPermissions, replacePrincipalRoles, addPrincipalRoles, removePrincipalRole |
| Native users | listNativeUsers, updateNativeUser, resetNativeUserPassword |
| Invitations | listInvitations, createInvitation, resendInvitation, revokeInvitation |
There is no admin “create user with password” API. Prefer invitations (createInvitation with roles) so users onboard with roles on accept. Self-serve signup via App SDK signup / hosted sign-up still works. Admins can also list users, update status / email_verified, and trigger password-reset emails.
Hosted auth vs headless
Hosted (recommended for browser apps)
Do not put the API key or admin credentials in the browser. Redirect users to IAM hosted pages:
https://iam.eficensittest.com/auth/sign-in?project_id=<PROJECT_UUID>&redirect_uri=<YOUR_APP_URL>&state=<OPTIONAL>| Path | Purpose |
|------|---------|
| /auth/sign-in | Native login |
| /auth/sign-up | Native signup |
| /auth/verify-email | Email verification |
| /auth/forgot-password | Request password reset |
| /auth/reset-password | Set new password |
| /auth/accept-invite | Accept project invitation |
Query params for sign-in / sign-up:
project_id(required)redirect_uri(optional) — after login, IAM redirects to{redirect_uri}?access_token=...&refresh_token=...&state=...state(optional) — echoed back on redirect
Use the returned access_token with your backend (which holds the API key) for introspect / check.
Headless (backend / server)
Call iam.login() / iam.signup() from your server with the project API key available for subsequent authz calls. Never expose the API key or admin credentials to end users.
Errors
Failed requests throw IamError:
import { IamClient, IamError } from "eficens-iam-sdk";
try {
await iam.login(email, password);
} catch (err) {
if (err instanceof IamError) {
console.error(err.status, err.message, err.detail);
}
throw err;
}Common status codes
| Status | Meaning | |--------|---------| | 401 | Invalid API key or access/refresh/admin token | | 403 | Not allowed, email not verified, or tenant/user disabled | | 429 | Rate limited (login endpoints) |
End-to-end example (Express-style)
import express from "express";
import { IamClient, IamError } from "eficens-iam-sdk";
const iam = new IamClient({
baseUrl: process.env.IAM_API_URL!,
projectId: process.env.IAM_PROJECT_ID!,
apiKey: process.env.IAM_API_KEY!,
});
const app = express();
app.use(express.json());
app.post("/login", async (req, res) => {
try {
const tokens = await iam.login(req.body.email, req.body.password);
res.json(tokens);
} catch (err) {
if (err instanceof IamError) return res.status(err.status || 400).json({ error: err.message });
throw err;
}
});
app.get("/todos", async (req, res) => {
const accessToken = req.headers.authorization?.replace(/^Bearer\s+/i, "") || "";
const allowed = await iam.check("todo.tasks.read", accessToken);
if (!allowed) return res.status(403).json({ error: "Forbidden" });
res.json([]);
});App API reference
| Method | Description |
|--------|-------------|
| signup(email, password) | Native signup → verification email |
| verifyEmail(token) | Confirm email |
| resendVerification(email) | Resend verification email |
| forgotPassword(email) | Request password reset email |
| resetPassword(token, newPassword) | Set new password from reset token |
| login(email, password) | Native password grant → tokens |
| refresh(refreshToken) | Refresh access token |
| exchangeIdToken(idToken) | Cognito/OIDC ID token → IAM tokens |
| introspect(accessToken) | Profile, roles, permissions |
| check(permission, accessToken) | Single permission → boolean |
| batchCheck(items, accessToken) | Multiple checks → { results } |
Support
Email: [email protected]
Include your project slug and approximate time of the issue. Do not send API keys or passwords.
