Intelligent Assistant
Chat with our virtual assistant to get answers promptly.
Cross-Account Protection, a security hardening component that complies with RISC of OpenID Foundation (OIDF), proactively guarantees the security for multiple accounts used to sign in to your app.
After subscribing to a specific security event, your app can use this component to receive abnormal events about HUAWEI ID changes (for example, a HUAWEI ID is frozen or hijacked) in a timely manner. You can proactively prevent and control errors based on the abnormal events to reduce the impact of an abnormal account on others.
For example, if a user's HUAWEI ID is hijacked, the attacker may use information about the HUAWEI ID, such as its email address, for a larger-scale hijacking. To prevent this, you can subscribe to events related to a HUAWEI ID. Once receiving a hijacking event of the HUAWEI ID, temporarily disable the sign-in using the HUAWEI ID.
Create a project, enable the RISC API for it, and create a service account key on the API console. For details, please refer to API Console Operation Guide.
After downloading the service account key file that you've created from the API console, keep it secure. It will be used for access token generation and signature verification later.
To enable Cross-Account Protection, your app needs to:
In this way, your app can receive the security event message from Huawei.
After completing the integration preparations, you need to register the event receiving service to subscribe to a security event and register the event message receiving URL with Huawei Cross-Account Protection.
The access token generated from a service account is a JWT string. For details about how to generate such an access token, please refer to Service Account-based Authentication.
The access token (validity period: 1 hour) can be used for calling the RISC API. When the access token expires, request a new one for calling the RISC API.
After an access token is generated locally, you can call the /v1beta/toolkit/risc/stream:update API to register the event receiving service with Huawei Cross-Account Protection, modify the configurations, and start or stop the delivery service.
- POST /v1beta/toolkit/risc/stream:update HTTP/1.1
- Host: risc.cloud.huawei.com
- Content-Type: application/json
- Authorization: Bearer <Access Token>
- Cache-Control: no-cache
- Postman-Token: 74f0e351-fdcb-c74a-ed63-670cb5926659
-
- {
- "iss": "id.cloud.huawei.com",
- "aud": [
- "<App ID-1>",
- "<App ID-2>",
- "<App ID-3>"
- ],
- "delivery": {
- "delivery_method": "https://schemas.openid.net/secevent/risc/delivery-method/push",
- "url": "<Event receiving URL>"
- },
- "events_requested": [
- "<Security event type-1>",
- "<Security event type-2>",
- "<Security event type-3>"
- ],
- "status": "enabled"
- }
Parameter |
Description |
|---|---|
iss |
Message sender ID. The value is always id.cloud.huawei.com. |
aud |
IDs of apps that you want to receive security event messages. Make sure that the app you specify here has gained user authorization. For details about the authorization process, please refer to Obtaining the Authorization from a User. |
delivery_method |
Delivery method. The value is always https://schemas.openid.net/secevent/risc/delivery-method/push. |
url |
URL through which you will receive security event messages for your apps. The URL must be an HTTPS URL with a specific domain name, and must be reachable. |
events_requested |
Type of the security event to be subscribed to. Multiple types of security events can be subscribed to at the same time. For details, please refer to security event types and measures. |
status |
Status of the event receiving service. The value can be disabled or enabled. |
The response of the successful registration is as follows:
- {
- "error": "{\"sub_error\":0,\"error_description\":\"success\",\"error\":0}"
- }
Call the /v1beta/toolkit/risc/stream API to obtain the configurations of the current event receiving service through the GET method, modify the response body, and call the /v1beta/toolkit/risc/stream:update API to update the modified configurations through the POST method to Huawei Cross-Account Protection.
Call the /v1beta/toolkit/risc/stream/status:update API to update the message body {"status": "disabled"} through the POST method to Huawei Cross-Account Protection to stop the message delivery. Conversely, update the message body {"status": "enabled"} to Huawei Cross-Account Protection to enable the delivery. You can also call the /v1beta/toolkit/risc/stream/status API to query the service status.
Before Huawei delivers a security event message to your app, your app must be authorized by the user to receive the security event of the user's account from Huawei.
The required permission is as follows:
Permission URL |
Description |
|---|---|
https://www.huawei.com/auth/account/riscdelivery |
Access HUAWEI ID security events to safeguard user accounts. |
The following is an example of the URL for obtaining user authorization:
- https://oauth-login.cloud.huawei.com/oauth2/v3/authorize?response_type=code&access_type=offline&state=state_parameter_passthrough_value&client_id=<App ID-1>&redirect_uri=<App redirection URL>&scope=openid+https://www.huawei.com/auth/account/riscdelivery&display=touch
For details about how to obtain user authorization, please refer to Authorization Code.
Huawei sends a security event message (signed by JWT) to your app. After receiving the message, you need to perform local signature verification on the message to ensure that the message is complete and valid, and then parse the message body to obtain the security event information.
Use any JWT library (for example, jwt.io) to verify and parse the signature.
No matter which library is used, you must perform the following operations:
Sample code:
- private DecodedJWT validateSecurityEventToken(String token) {
- DecodedJWT jwt = null;
- try {
- // Replace the values with the actual ones obtained from https://risc.cloud.huawei.com/v1beta/public/risc/.well-known/risc-configuration
- String issuer = "id.cloud.huawei.com";
- String jwksUri = "https://risc.cloud.huawei.com/v1beta/public/risc/certs";
-
- // Get the ID of the key used to sign the token.
- DecodedJWT unverifiedJwt = JWT.decode(token);
- String keyId = unverifiedJwt.getKeyId();
-
- // Get the public key from Huawei.
- JwkProvider huaweiCerts = new UrlJwkProvider(new URL(jwksUri), null, null);
- PublicKey publicKey = huaweiCerts.get(keyId).getPublicKey();
-
- // Verify and decode the token.
- Algorithm rsa = Algorithm.RSA256((RSAPublicKey) publicKey, null);
- JWTVerifier verifier = JWT.require(rsa)
- .withIssuer(issuer)
- // client_id<->aud:
- .withAudience(unverifiedJwt.getAudience().get(0))
- .acceptLeeway(60 * 1000)
- .build();
- jwt = verifier.verify(token);
- } catch (JwkException e) {
- // Key not found. Return HTTP 400.
- } catch (InvalidClaimException e) {
- e.printStackTrace();
- } catch (JWTDecodeException e) {
- // Malformed token. Return HTTP 400.
- e.printStackTrace();
- } catch (MalformedURLException e) {
- // Invalid JWKS URI.
- e.printStackTrace();
- }
- return jwt;
- }
After the local signature verification, you can decode the message body in JWT format. For details, please refer to JSON Web Token. The following is an example of the decoded message body:
- {
- "aud": "<App ID>",
- "iss": "id.cloud.huawei.com",
- "iat": 1588675381042,
- "jti": "6672ed7d5c5e4c3c92f343ecac40f326",
- "events": {
- "https://schemas.openid.net/secevent/risc/event-type/account-purged": {
- "subject": {
- "sub": "<UnionID of the user who triggers an event>",
- "subject_type": "iss_sub",
- "extra": "<OpenID of the user who triggers an event>",
- "iss": "id.cloud.huawei.com"
- }
- }
- }
- }
The parameters in the preceding code are described as follows.
Parameter |
Description |
|---|---|
aud |
App ID, which is the same as the value of sub_account in the downloaded key file in Integration Preparations. |
iss |
Message sender ID. The value is always id.cloud.huawei.com. |
iat |
UTC timestamp when an event is generated. |
jti |
Unique random character string, which helps you to identify the redelivered message body. |
events |
Specific security event type and corresponding message body. |
subject |
|
You can take proper measures based on the event type.
The event types and measures are as follows.
Event Type |
Attribute |
Solution |
|---|---|---|
https://schemas.openid.net/secevent/oauth/event-type/tokens-revoked |
OAuth-based proactive authorization cancellation |
If an access token is used for sign-in with a HUAWEI ID, terminate the current session. In addition, you are advised to prompt the user to select another sign-in method. If the access token is used to access other Huawei APIs, delete any other OAuth access token that you have stored for the user. |
https://schemas.openid.net/secevent/risc/event-type/account-disabled |
Account hijacking or being regarded as one of batch junk accounts |
If the account is disabled due to hijacking, terminate the current session to prevent the account information from being stolen. If an account is disabled because it is regarded as one of batch junk accounts, analyze the user behavior on your app and determine the subsequent measures. If no reason is provided, prohibit the user from signing in with the HUAWEI ID or recovering this ID, and provide alternative sign-in methods to the user. |
https://schemas.openid.net/secevent/risc/event-type/account-enabled |
Account unfreezing |
Re-enable the sign-in with the HUAWEI ID for the user and allow the user to use the associated email address to reactivate the account. |
https://schemas.openid.net/secevent/risc/event-type/account-purged |
Account deregistration |
Delete the account information and provide the user with alternative sign-in methods. |
https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required |
Password change |
Check whether your app has suspicious behavior and take proper measures. |
https://schemas.openid.net/secevent/risc/event-type/verification |
Verification message |
Record the received verification message. |
Call the /v1beta/toolkit/risc/stream:verify API to check whether cross-account protection works properly after you complete the following operations: registering the event receiving service, obtaining the user authorization, verifying the signature on the received message body, and parsing the message body.
Request example:
Send a POST request. Example:
- POST /v1beta/toolkit/risc/stream:verify HTTP/1.1
- Host: risc.cloud.huawei.com
- Content-Type: application/json
- Authorization: Bearer <Access Token>
- Cache-Control: no-cache
- Postman-Token: c67f7a42-9118-9d70-c37c-d8763cdb0489
-
- {"state":"RISC Test message form client_id of Tester!!!"}
Response example:
- {
- "error": "{\"sub_error\":0,\"error_description\":\"success\",\"error\":0}"
- }
Error Code |
Sub-error Code |
Description |
Status Code |
|---|---|---|---|
3201 |
70001102 |
Unauthorized. |
401 |
3202 |
70003001 |
The value of delivery_method is not an HTTPS URL. |
403 |
3202 |
70003002 |
Stream configurations do not have specifications-compliant delivery method for RISC. |
403 |
3202 |
70003003 |
The app does not exist. |
403 |
3202 |
70003005 |
The RISC API can be called only by the service account. |
403 |
3202 |
70003006 |
The delivery method does not belong to the project domain. |
403 |
3202 |
70003007 |
The RISC API caller does not own the app ID. |
403 |
3202 |
70003008 |
Unsupported RISC status. Currently, only enabled and disabled are supported. |
403 |
3202 |
70003009 |
Failed to update the status because no RISC configuration exists. |
403 |
3202 |
70003010 |
Failed to query RISC configurations because no configuration exists. |
403 |
3202 |
70003011 |
The specified subject cannot be added. |
403 |
3202 |
70003012 |
The specified subject cannot be removed. |
403 |
3202 |
70003013 |
Parameter error. |
403 |
3203 |
70003201 |
The subject cannot be identified. |
404 |
3204 |
70003401 |
Too frequent sending in the specified time frame. |
429 |
3205 |
70001401 |
Internal system error. |
500 |
3205 |
70001402 |
Cross-Account Protection is unavailable as it is now under maintenance. |
500 |