Install
openclaw skills install iam-integrationUse when integrating a new service with the IAM (Identity and Access Management) system - covers gRPC client setup, JWT token validation, permission checks, and REST API usage for the changyuanfeilun platform.
openclaw skills install iam-integrationIAM is the central identity service. Services integrate via gRPC (primary) or REST. All resources are scoped by appCode + tenantCode.
| Need | Method | Endpoint/Service |
|---|---|---|
| Validate JWT token | gRPC | JwtTokenService.validateAccessToken |
| Check permission | gRPC | AuthorizationService.hasPermission |
| Get user by UID | gRPC | AccountService.GetByUid |
| Login | REST | POST /api/v1.0/login/generateTicket |
| Exchange ticket for token | REST | POST /api/v1.0/account/exchangeAuthTicket |
| Get current user | REST | GET /api/v1.0/account/current |
<dependency>
<groupId>com.feilun</groupId>
<artifactId>iam-rich-client</artifactId>
</dependency>
<dependency>
<groupId>com.feilun</groupId>
<artifactId>iam-boot-starter</artifactId>
</dependency>
grpc:
client:
iam-service:
address: dns:///iam.${namespace}.svc.cluster.local:9090
negotiation-type: plaintext
@Autowired JwtTokenRichClient jwtTokenClient;
// Validate token (with optional permission check)
ValidateAccessTokenRequest req = ValidateAccessTokenRequest.newBuilder()
.setAccessToken(token)
.setAppCode(appCode)
.setTenantCode(tenantCode)
// optional: add permission check
.setPermissionCheck(PermissionCheck.newBuilder()
.setObject("resource-name")
.setAct("read")
.build())
.build();
ValidateAccessTokenResponse resp = jwtTokenClient.validateAccessToken(req);
// resp.getUid(), resp.getRoleCodesList(), resp.getValid()
@Autowired AuthorizationRichClient authClient;
HasPermissionRequest req = HasPermissionRequest.newBuilder()
.setAppCode(appCode)
.setTenantCode(tenantCode)
.setSubject(uid)
.setObject("resource-name")
.setAct("write")
.setSiteCode(siteCode)
.build();
boolean allowed = authClient.hasPermission(req).getHasPermission();
@Autowired AccountRichClient accountClient;
GetByUidRequest req = GetByUidRequest.newBuilder()
.setUid(uid).setAppCode(appCode).setTenantCode(tenantCode)
.build();
AccountProto account = accountClient.getByUid(req).getAccount();
| Header | Description |
|---|---|
X-ACCESS-TOKEN | JWT token |
X-App | App code |
X-Tenant | Tenant code |
X-Uid | User UID (set by gateway) |
X-IS-MOBILE | true / false |
Add IamAuthInfoFilter to your service to auto-extract auth context from headers into thread-local.
// Access current user context anywhere in request thread
IamAuthContext ctx = IamAuthContextHolder.get();
String uid = ctx.getUid();
String tenantCode = ctx.getTenantCode();
Account: uid, appCode, tenantCode, loginName, email, mobile,
acctStatus(0=inactive,1=active,2=disabled,9=cancelled),
acctType(0=sub,1=main), roleCodes[], siteScope[]
Authorization: subject(uid/role), object(resource), act(read/write/delete),
permitAll(bool), permitTargetId[], permitObjectId[]
appCode + tenantCodeiam_jwt_secret table)siteCode when checking| Mistake | Fix |
|---|---|
Missing appCode/tenantCode | Always required in every gRPC request |
Checking permission without siteCode | Pass siteCode for site-scoped resources |
Calling REST without X-App/X-Tenant headers | Required for all REST calls |
Using system mvn to build | Use ./mvnw — project requires Maven 3.8.x via wrapper |
| Code | Status |
|---|---|
| 0 | Inactive (pending activation) |
| 1 | Active |
| 2 | Disabled |
| 3 | Locked |
| 8 | Cancellation in progress |
| 9 | Cancelled |