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
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
/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' 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
401 | Chưa đăng nhập / phiên hết hạn → `{ "authenticated": false }` |
/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ên | Kiểu | Mô 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) /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ường | Kiểu | Mô 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=1 | Sai thông tin đăng nhập (redirect kèm lỗi) |
/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ường | Kiểu | Mô 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. /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ường | Kiểu | Mô 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|exists | Thiếu trường / email đã tồn tại |
/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
/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ên | Kiểu | Mô 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)
/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ường | Kiểu | Mô 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
} /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ường | Kiểu | Mô 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
} /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ường | Kiểu | Mô 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
400 | Thiếu credential cần xác minh |
/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ường | Kiểu | Mô tả |
|---|---|---|
id* | string | ID credential (`vc_…`) |
Phản hồi mẫu
{ "ok": true } /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ên | Kiểu | Mô 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)
/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ường | Kiểu | Mô 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
} /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ường | Kiểu | Mô 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)
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