API Reference

DXA Identity API

Định danh, SSO & xác thực số cho toàn hệ sinh thái

DXA Identity là dịch vụ CIAM đa realm trung tâm. Mọi sản phẩm trong hệ sinh thái dùng chung một phiên đăng nhập (SSO) qua cookie `xv_session` trên miền `.dxa.io.vn`. App tích hợp xác thực người dùng bằng endpoint introspection, redirect tới trang đăng nhập trung tâm, hoặc nâng cấp mức đảm bảo (step-up) khi cần. Ngoài ra hỗ trợ định danh phi tập trung (DID/VC), ví số (OpenID4VCI), và xác thực máy-máy (service client).

Base URL

https://identity.dxa.io.vn

Xác thực

Phiên kiểu Lucia: token lưu trong cookie `xv_session` (HttpOnly, Domain=.dxa.io.vn). Để xác thực người dùng từ app của bạn, gọi `GET /api/session` kèm cookie — trình duyệt tự gửi cookie cho mọi subdomain. Realm mặc định là `dxa`. Phiên ghi nhận phương thức xác thực (`amr`) và mức đảm bảo (`aal`: AAL1/AAL2/AAL3). Tích hợp máy-máy dùng Bearer token của service client.

Xác thực & Phiên

GET /api/session

Introspection phiên hiện tại — kèm amr/aal (CORS cho *.dxa.io.vn)

Xác thực: Cookie `xv_session` (tự gửi)

Ví dụ yêu cầu

curl 'https://identity.dxa.io.vn/api/session' \
  -H 'Cookie: xv_session=<token>' \
  -H 'Origin: https://your-app.dxa.io.vn'
const res = await fetch('https://identity.dxa.io.vn/api/session', {
  credentials: 'include', // gửi cookie xv_session
});
const session = await res.json();
if (session.authenticated && session.aal === 'AAL2') {
  console.log(session.user.email, session.memberships);
}

Phản hồi mẫu

{
  "authenticated": true,
  "realmId": "dxa",
  "user": {
    "id": "usr_8f2c…",
    "email": "dev@partner.vn",
    "name": "Nguyễn An",
    "avatar_color": "#24467e"
  },
  "memberships": [
    { "org_id": "org_12ab", "org_name": "Đối tác ABC", "role": "admin" }
  ],
  "amr": ["pwd", "otp"],
  "aal": "AAL2"
}

Mã lỗi

401Chưa đăng nhập / phiên hết hạn → `{ "authenticated": false }`
GET /step-up

Nâng mức đảm bảo (step-up) lên AAL2/AAL3 rồi quay lại app

Xác thực: Cookie `xv_session` (tuỳ chọn)

Tham số

TênKiểuMô tả
redirect* string URL quay lại (phải thuộc *.dxa.io.vn hoặc localhost)
aal 'AAL1' | 'AAL2' | 'AAL3' Mức đảm bảo yêu cầu (mặc định AAL2)

Ví dụ yêu cầu

https://identity.dxa.io.vn/step-up
  ?aal=AAL2
  &redirect=https://your-app.dxa.io.vn/secure-action

Phản hồi mẫu

// 302 Redirect:
//  • Phiên hiện tại đã đạt mức AAL yêu cầu → quay lại <redirect>
//  • Chưa đạt / chưa đăng nhập → /login?aal=AAL2&redirect=<url> (buộc xác thực lại)
POST /api/auth/login

Đăng nhập bằng email + mật khẩu (form)

Xác thực: Không (công khai)

Tham số (body)

TrườngKiểuMô tả
email* string Email người dùng
password* string Mật khẩu
realm string Realm (mặc định `dxa`)

Ví dụ yêu cầu

curl -X POST 'https://identity.dxa.io.vn/api/auth/login' \
  -H 'Origin: https://identity.dxa.io.vn' \
  -F 'email=dev@partner.vn' \
  -F 'password=••••••••'

Phản hồi mẫu

// 303 Redirect — đặt cookie xv_session, chuyển tới /account hoặc redirect đã validate.
// Nếu user bật 2FA → chuyển sang /login/2fa (đặt cookie xv_mfa tạm thời).

Mã lỗi

303 ?error=1Sai thông tin đăng nhập (redirect kèm lỗi)
POST /api/auth/2fa

Xác minh mã TOTP / mã khôi phục (bước 2FA của đăng nhập)

Xác thực: Cookie `xv_mfa` (từ bước login)

Tham số (body)

TrườngKiểuMô tả
code* string Mã TOTP 6 số hoặc mã khôi phục

Phản hồi mẫu

// 303 Redirect — tạo phiên thật (amr: ["pwd","otp"], aal: AAL2),
// đặt cookie xv_session và xoá cookie xv_mfa.
POST /api/auth/register

Đăng ký dùng thử — tạo tenant + người dùng admin (realm `dxa`)

Xác thực: Không (công khai)

Tham số (body)

TrườngKiểuMô tả
email* string Email admin
password* string Mật khẩu (tối thiểu 6 ký tự)
name* string Tên người dùng
orgName* string Tên tổ chức (tenant)

Phản hồi mẫu

// 303 Redirect — đặt cookie xv_session, chuyển tới /account.

Mã lỗi

303 ?error=invalid|existsThiếu trường / email đã tồn tại
POST /api/auth/logout

Đăng xuất — vô hiệu hóa phiên & xóa cookie

Xác thực: Cookie `xv_session`

Phản hồi mẫu

// 303 Redirect — xoá cookie xv_session/xv_org, chuyển về /login.

Tổ chức

GET /api/org/resolve

Tra cứu tổ chức công khai (DID + trạng thái xác minh KYC)

Xác thực: Không (công khai, CORS *)

Tham số

TênKiểuMô tả
org_id string ID tổ chức (hoặc dùng `slug`)
slug string Slug tổ chức (hoặc dùng `org_id`)

Ví dụ yêu cầu

curl 'https://identity.dxa.io.vn/api/org/resolve?slug=doi-tac-abc'

Phản hồi mẫu

{
  "org_id": "org_12ab",
  "name": "Đối tác ABC",
  "did": "did:web:identity.dxa.io.vn",
  "org_did": "did:web:identity.dxa.io.vn:o:org_12ab",
  "verified": true,
  "verified_at": "2026-05-01T00:00:00Z",
  "realm": "dxa"
}

Định danh phi tập trung (DID / VC)

POST /api/did/issue

Cấp Verifiable Credential (SD-JWT) cho người dùng hoặc tổ chức

Xác thực: Cookie `xv_session`, hoặc Bearer token service client (scope `did:issue`)

Tham số (body)

TrườngKiểuMô tả
type* 'IdentityCredential' | 'MembershipCredential' | 'OrganizationAttestation' Loại credential
org_id string Tổ chức (bắt buộc cho OrganizationAttestation; tuỳ chọn cho Membership)
claims object Claim tuỳ biến (chỉ cho OrganizationAttestation)

Phản hồi mẫu

{
  "id": "vc_7d21…",
  "type": "IdentityCredential",
  "vct": "https://identity.dxa.io.vn/vc/IdentityCredential",
  "issuer": "did:web:identity.dxa.io.vn",
  "subject": "did:web:identity.dxa.io.vn:u:usr_8f2c",
  "claims": { "email": "dev@partner.vn", "name": "Nguyễn An" },
  "sdjwt": "eyJhbGciOiJFUzI1Ni…~WyJ…",
  "issuedAt": "2026-06-01T00:00:00Z",
  "expiresAt": 1798675200
}
POST /api/did/offer

Tạo Credential Offer OpenID4VCI (pre-authorized code, PIN tuỳ chọn)

Xác thực: Cookie `xv_session`

Tham số (body)

TrườngKiểuMô tả
type string Loại credential (hoặc mảng `types`)
org_id string Tổ chức (cho MembershipCredential)
pin boolean Bật mã PIN (tx_code) bảo vệ offer

Phản hồi mẫu

{
  "offer": {
    "credential_issuer": "https://identity.dxa.io.vn",
    "credential_configuration_ids": ["IdentityCredential"],
    "grants": {
      "urn:ietf:params:oauth:grant-type:pre-authorized_code": {
        "pre-authorized_code": "…",
        "tx_code": { "length": 4, "input_mode": "numeric" }
      }
    }
  },
  "offerUri": "openid-credential-offer://?credential_offer=…",
  "txCode": "1234",
  "expiresAt": 1798675200
}
POST /api/did/verify

Xác minh chữ ký SD-JWT VC (có/không Key Binding)

Xác thực: Không (công khai, CORS *)

Tham số (body)

TrườngKiểuMô tả
token* string Chuỗi SD-JWT cần xác minh (cũng nhận `sdjwt`/`credential`)
nonce string Nonce để kiểm Key Binding

Ví dụ yêu cầu

curl -X POST 'https://identity.dxa.io.vn/api/did/verify' \
  -H 'Content-Type: application/json' \
  -d '{ "token": "eyJhbGciOiJF…" }'

Phản hồi mẫu

{
  "valid": true,
  "iss": "did:web:identity.dxa.io.vn",
  "sub": "did:web:identity.dxa.io.vn:u:usr_8f2c",
  "vct": "https://identity.dxa.io.vn/vc/IdentityCredential",
  "payload": { "email": "dev@partner.vn", "name": "Nguyễn An" },
  "exp": 1798675200,
  "iat": 1767139200
}

Mã lỗi

400Thiếu credential cần xác minh
POST /api/did/revoke

Thu hồi một credential đã cấp

Xác thực: Cookie `xv_session` (chủ sở hữu credential)

Tham số (body)

TrườngKiểuMô tả
id* string ID credential (`vc_…`)

Phản hồi mẫu

{ "ok": true }
GET /vc/{type}

Metadata loại VC (cho ví số hiển thị)

Xác thực: Không (công khai, CORS *)

Tham số

TênKiểuMô tả
type* 'IdentityCredential' | 'MembershipCredential' | 'OrganizationAttestation' Loại VC trong đường dẫn

Phản hồi mẫu

{
  "vct": "https://identity.dxa.io.vn/vc/IdentityCredential",
  "name": "DXA Identity",
  "description": "…",
  "claims": {
    "email": { "name": "Email", "required": true },
    "name": { "name": "Họ tên" }
  }
}

Ví số (OpenID4VCI)

POST /api/oid4vci/token

Đổi pre-authorized code lấy access token + c_nonce

Xác thực: Không (pre-authorized code flow)

Tham số (body)

TrườngKiểuMô tả
grant_type* string `urn:ietf:params:oauth:grant-type:pre-authorized_code`
pre-authorized_code* string Mã từ Credential Offer
tx_code string Mã PIN (nếu offer có bảo vệ)

Phản hồi mẫu

{
  "access_token": "…",
  "token_type": "bearer",
  "expires_in": 600,
  "c_nonce": "…",
  "c_nonce_expires_in": 600
}
POST /api/oid4vci/credential

Nhận VC bằng access token + proof-of-possession (key binding)

Xác thực: Bearer token (từ endpoint token)

Tham số (body)

TrườngKiểuMô tả
credential_configuration_id* string Loại credential, vd `IdentityCredential`
proof* object JWT proof (`proof_type: "jwt"`) chứa khoá công khai của ví trong header

Phản hồi mẫu

{
  "credentials": [ { "credential": "eyJhbGciOiJF…" } ],
  "credential": "eyJhbGciOiJF…"
}

Tích hợp máy-máy (Service client)

POST Authorization: Bearer <service_token>

Xác thực máy-máy cho các thao tác phía máy chủ (vd cấp VC tổ chức)

Xác thực: Bearer token service client (token_hash lưu D1, có scope)

Ví dụ yêu cầu

curl -X POST 'https://identity.dxa.io.vn/api/did/issue' \
  -H 'Authorization: Bearer <service_token>' \
  -H 'Content-Type: application/json' \
  -d '{ "type": "OrganizationAttestation", "org_id": "org_12ab",
        "claims": { "docType": "invoice", "docId": "INV-2026-001" } }'

Phản hồi mẫu

// Service client là tài khoản máy gắn với một realm/tổ chức và danh sách scope.
// Dùng cho luồng đầu-cuối không có người dùng — ví dụ DXA Blockchain/Trustway
// gọi /api/did/issue với scope ["did:issue"] để cấp OrganizationAttestation.
//
// Authorization: Bearer <service_token>
//   • token_hash = sha256(token) lưu trong bảng service_clients
//   • scopes: ["did:issue", …]   • org_id: null = mọi tổ chức trong realm