AIP-147

Sensitive fields

Sometimes APIs need to collect sensitive information such as private encryption keys meant to be stored by the underlying service but not intended to be read after writing due to the sensitive nature of the data. For this type of data, extra consideration is required for the representation of the sensitive data in API requests and responses.

Guidance

If the sensitive information is required for the resource as a whole to exist, the data should be accepted as an input-only field with no corresponding output field. Because the sensitive data must be present for the resource to exist, users of the API may assume that existence of the resource implies storage of the sensitive data. For example:

message SelfManagedKeypair {
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // The public key data in PEM-encoded form.
  bytes public_key = 2;

  // The private key data in PEM-encoded form.
  bytes private_key = 3 [
    (google.api.field_behavior) = INPUT_ONLY];
}

If the sensitive information is optional within the containing resource, an output-only boolean field with a postfix of _set should be used to indicate whether or not the sensitive information is present. For example:

message Integration {
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];
  string uri = 2;

  // A secret to be passed in the `Authorization` header of the webhook.
  string shared_secret = 3 [
    (google.api.field_behavior) = INPUT_ONLY];

  // True if a `shared_secret` has been set for this Integration.
  bool shared_secret_set = 4 [
    (google.api.field_behavior) = OUTPUT_ONLY];
}

If it is important to be able to identify the sensitive information without allowing it to be read back entirely, a field of the same type with an obfuscated_ prefix may be used instead of the boolean _set field to provide contextual information about the sensitive information. The specific nature of the obfuscation is outside the scope of this AIP. For example:

message AccountRecoverySettings {
  // An email to use for account recovery.
  string email = 1 [
    (google.api.field_behavior) = INPUT_ONLY];

  // An obfuscated representation of the recovery email. For example,
  // `ada@example.com` might be represented as `a**@e*****e.com`.
  string obfuscated_email = 2 [
    (google.api.field_behavior) = OUTPUT_ONLY];
}