All Products
Search
Document Center

PolarDB:Grant access permissions on multi-user data

Last Updated:Mar 28, 2026

In an always-confidential database cluster, each user's data is encrypted with their own data encryption key (DEK) and automatically isolated from other users. To enable multi-party data integration and joint computation, issue a behavior control list (BCL) to grant an applicant access to another user's ciphertext data.

Prerequisites

Before you begin, ensure that you have:

How BCL authorization works

BCL authorization involves two parties:

PartyRoleCertificate field
Data owner (issuer)Owns the encrypted data. Reviews and approves or rejects access requests.issuer_pukid
Applicant (subject)Requests access to the data owner's ciphertext for joint computation.subject_pukid

After a BCL is issued, the applicant can query the data owner's ciphertext within the scope defined by the BCL. Only the final computation result is accessible — intermediate data remains unavailable.

Use case

An advertising platform wants to identify users under 30 from a data platform's encrypted user profile table. The data platform owns the DEK and the applicant (the advertising platform) holds its own DEK. Without authorization, the applicant can only see ciphertext and cannot use the data.

To proceed:

  1. The applicant submits a BCL authorization request specifying which DEK groups and operations are needed.

  2. The data platform reviews and signs the BCL to approve access.

  3. After approval, the advertising platform can query the user profile data within the authorized scope.

Grant BCL authorization

Step 1: Initialize certificates

Both parties must register their certificates in the application code before calling any BCL APIs. The following code registers the participant's certificate with the KeyManager. Key registration is required only once per session.

// The private key of the participant's certificate.
String userPriPemString = "*****";
// The public key of the participant's certificate.
String userPukPemString = "*****";

// Initialize the KeyManager and register the certificate.
KeyManager km = sdk.getKeyManager();
km.registerCertificate(userPriPemString, userPukPemString);

Step 2: Collect required parameter values

Before defining the BCL JSON body, collect the following values. Both the applicant and data owner need these values.

Certificate thumbprints (`issuer_pukid` and `subject_pukid`)

A certificate thumbprint is the SHA-256 hash of the certificate content, encoded in Base64:

  1. Compute the SHA-256 hash of the full certificate content, including the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- markers. You can specify a different hash algorithm if needed.

  2. Base64-encode the hash.

  3. Use the resulting string as the thumbprint value.

DEK group values (`groupid`, `min`, `max`)

Run the following SQL statement to retrieve the groupid and DEK ID (dekid) for a given encrypted column:

SELECT encdb_get_cc_entry_by_name(<keyname>);

Set <keyname> to the name of the column on which the applicant needs access. The result contains the groupid and the DEK IDs that define the range (min and max).

Step 3: Define the BCL JSON body

Construct the BCL JSON body with the values collected in Step 2. The issueBCL method uses this JSON body for both the applicant's request and the data owner's approval.

String bclBodyJsonString = """
{
  "version": 1,
  "serial_num": "a121bac0-5cb3-4463-a2b2-1155ff29f4c8",

  "issuer_pukid": "dYJ3Wfj/n0eZbuqgQjv8bnBdPXGyWGOlxE/uMy16NXo=",
  "subject_pukid": "+Gg4vXehPt9BWlCPdR83wKDn6E1b/XddNhKQ5mVbKVQ=",

  "validity": {
    "not_before": "20220820111111+0800",
    "not_after":  "20230820111111+0800"
  },
  "policies": {
    "issuer_dek_group": [
      { "min": 1, "max": 100000, "groupid": "b6785611-0c49-4f13-87a9-13f151de9b4d" }
    ],
    "subject_dek_group": [
      { "min": 1, "max": 100000, "groupid": "5e19cfa7-c001-4e44-acab-2e5de4b97dcb" }
    ],
    "result_dek": "SUBJECT",
    "operation": ["*"],
    "preproc":  "NULL",
    "postproc": "NULL"
  }
}
""";

The following table describes each parameter.

ParameterExampleDescription
version1Version number. Set to 1.
serial_num"a121bac0-5cb3-4463-a2b2-1155ff29f4c8"A unique, random serial number in universally unique identifier (UUID) format.
issuer_pukid"dYJ3Wfj/..."Certificate thumbprint of the data owner. See Step 2 for how to compute this value.
subject_pukid"+Gg4vXehPt9..."Certificate thumbprint of the applicant. Computed the same way as issuer_pukid.
validity.not_before"20220820111111+0800"Start of the authorization validity period, in GeneralizedTime format.
validity.not_after"20230820111111+0800"End of the authorization validity period, in GeneralizedTime format.
policies.issuer_dek_group[].groupid"b6785611-..."ID of the DEK group owned by the data owner. To get this value, run SELECT encdb_get_cc_entry_by_name(<keyname>).
policies.issuer_dek_group[].min1Smallest DEK ID in the data owner's group.
policies.issuer_dek_group[].max100000Largest DEK ID in the data owner's group.
policies.subject_dek_group[].groupid"5e19cfa7-..."ID of the DEK group owned by the applicant. To get this value, run SELECT encdb_get_cc_entry_by_name(<keyname>).
policies.subject_dek_group[].min1Smallest DEK ID in the applicant's group.
policies.subject_dek_group[].max100000Largest DEK ID in the applicant's group.
policies.result_dek"SUBJECT"DEK used to encrypt the computation result. Valid values: "SUBJECT" (applicant's DEK), "ISSUER" (data owner's DEK), or a specific DEK ID (specified without enclosing the value in double quotation marks).
policies.operation["*"]Allowed computation operations. Valid values: "encrypt", "decrypt", "cmp" (comparison), or "*" (all operations).
policies.preproc"NULL"Pre-processing operation before computation. Set to NULL if none is required.
policies.postproc"NULL"Post-processing operation after computation. Set to NULL if none is required.

Step 4: Applicant — submit the authorization request

The applicant calls issueBCL with isIssuer set to false. This signs the BCL JSON body with the applicant's private key and submits the authorization request to the data owner.

boolean isIssuer = false;
bclBodyJsonString = km.issueBCL(bclBodyJsonString, userPukPemString, userPriPemString, isIssuer);

Step 5: Data owner — approve and issue the BCL

The data owner reviews the BCL JSON body and, if approved, calls issueBCL with isIssuer set to true. This signs the BCL with the data owner's private key and issues the authorization.

boolean isIssuer = true;
bclBodyJsonString = km.issueBCL(bclBodyJsonString, userPukPemString, userPriPemString, isIssuer);

After this step, the applicant can query the data owner's ciphertext within the scope defined by the BCL.

Revoke BCL authorization

Revoke a BCL when the authorization period ends, the collaboration terminates, or a security incident requires immediate access removal. Revocation is performed by the data owner.

Step 1: Define the revocation list

Construct the behavior revocation list (BRL) JSON body. The serial_num value must match the serial number in the BCL you want to revoke.

String brlBodyJsonString = """
{
  "version": 1,
  "pukid": "dYJ3Wfj/n0eZbuqgQjv8bnBdPXGyWGOlxE/uMy16NXo=",
  "this_update": "20220819111128+0800",
  "next_update": "20220919111128+0800",
  "revoked": [
    {
      "revocation_date": "20220819111128+0800",
      "serial_num": "a121bac0-5cb3-4463-a2b2-1155ff29f4c8"
    }
  ]
}
""";

The following table describes each parameter.

ParameterExampleDescription
version1Version number. Set to 1.
pukid"dYJ3Wfj/..."Certificate thumbprint of the data owner. Must match the issuer_pukid in the original BCL.
this_update"20220819111128+0800"The point in time at which the revocation list is updated, in GeneralizedTime format.
next_update"20220919111128+0800"Timestamp of the next scheduled revocation list update, in GeneralizedTime format.
revoked[].revocation_date"20220819111128+0800"Timestamp when the specific BCL authorization is revoked, in GeneralizedTime format.
revoked[].serial_num"a121bac0-..."Serial number of the BCL to revoke. Must match the serial_num in the original BCL authorization.

Step 2: Data owner — issue the revocation

The data owner calls revokeBCL to sign and submit the BRL. After this call, the applicant loses access to the data owner's ciphertext.

brlBodyJsonString = km.revokeBCL(brlBodyJsonString, userPukPemString, userPriPemString);