forked from baron/baron-sso
3.0 KiB
3.0 KiB
Custom Field JSONB 및 인덱스 정책
현재 구조
- Tenant custom schema는
tenants.config.userSchemaJSONB에 저장한다. - Tenant custom value는 backend DB의
users.metadataJSONB에 저장한다. isLoginId=true인 Tenant field 값은 로그인 식별자 처리를 위해user_login_ids에도 동기화한다.- Ory Kratos traits에는 인증/식별에 필요한 최소 값만 동기화하는 방향으로 정리한다.
- RP custom value는 backend DB의
rp_user_metadata.metadataJSONB에 별도 저장한다.
Tenant Custom Field
Tenant schema field는 다음 속성을 기준으로 한다.
{
"key": "employeeNo",
"label": "사번",
"type": "text",
"required": false,
"indexed": true,
"isLoginId": true,
"adminOnly": false,
"validation": "^[A-Z0-9]+$"
}
indexed=true는 검색/필터 최적화 대상이라는 의미다.isLoginId=true이면 backend와 adminfront 모두indexed=true를 강제한다.isLoginId=true는 값 필수를 의미하지 않는다. 값 필수 여부는required=true로 별도 제어한다.isLoginId=true인 field는type=text만 허용한다.- JSONB 통합 정책에서는
varchar크기 지정 의미를 두지 않는다.
RP Custom Field
RP custom schema는 client metadata의 customUserSchema에 저장한다.
{
"customUserSchema": [
{
"key": "approvalLevel",
"label": "승인 등급",
"type": "text",
"required": false,
"indexed": true,
"claimEnabled": true
}
]
}
RP custom value는 rp_user_metadata 테이블에 저장한다.
client_id text
user_id uuid
metadata jsonb
created_at timestamptz
updated_at timestamptz
primary key (client_id, user_id)
foreign key (user_id) references users(id)
Backend API 초안:
GET /api/v1/dev/clients/:id/users/:userId/metadata
PUT /api/v1/dev/clients/:id/users/:userId/metadata
PUT payload:
{
"metadata": {
"approvalLevel": "A",
"preferences": {
"theme": "dark"
}
}
}
검색 및 인덱스
indexed=truefield만 검색 UI/API 후보로 노출한다.- 기본 검색은 exact match, exists, JSON containment 중심으로 제한한다.
- RP custom field의 LIKE/fuzzy 검색은 기본 제공하지 않는다.
- GIN 인덱스는 backend index manager가 별도 상태로 관리하는 방향을 원칙으로 한다.
- API 요청 처리 중
CREATE INDEX를 동기 실행하지 않는다.
Claim Projection
JWT 또는 userinfo 응답에서는 custom field를 top-level에 풀지 않는다. Tenant/RP 단위로 묶어서 전달한다.
{
"tenant_profiles": [
{
"tenant_id": "tenant-uuid",
"tenant_slug": "hanmac-family",
"fields": {
"employeeNo": "E1001"
}
}
],
"rp_profiles": [
{
"client_id": "sample-rp",
"fields": {
"approvalLevel": "A"
}
}
]
}
claimEnabled=truefield만 RP claim 후보로 포함한다.- 긴 JSON 값은 기본적으로 token claim보다 userinfo/profile API 응답에 싣는 방향을 우선한다.