Estrategias de privacidad de los datos

La privacidad de los datos protege los datos, como la información de identificación personal (PII), de aquellos que no deberían tener acceso a ellos. En esta página, se describen varios enfoques para la privacidad de los datos que puedes usar para proteger tu PII en Cloud SQL.

Puedes usar Cloud SQL para almacenar tu PII de forma segura. Se recomienda que esta información se procese con la mayor protección de la privacidad para que no se pueda acceder a ella de manera inadvertida. Por ejemplo, si almacenas información de la tarjeta de crédito o los datos de atención médica en tus bases de datos, puedes usar Cloud SQL para ocultar o enmascarar la PII de los usuarios sin privilegios.

Usa las siguientes estrategias para proteger tu PII en Cloud SQL:

Seguridad a nivel de la columna

La seguridad a nivel de la columna te permite restringir quién puede ver el contenido en columnas específicas de tablas de bases de datos. Los privilegios a nivel de la columna se aplican a las sentencias INSERT, UPDATE, SELECT y REFERENCES.

Por ejemplo, considera un sitio web de venta minorista en el que deseas controlar la PII para dos usuarios: Josué y Alicia.

--User: "admin"

CREATE SCHEMA secure_schema;

CREATE TABLE secure_schema.user_details(id bigint, name text, age smallint, email_id text, password text);

--For this example, passwords are stored in plain text for demonstration
--purposes only. In production, never store passwords in plain text.

INSERT INTO secure_schema.user_details VALUES(1,'jack',34,'jack@example.com','testpass');
INSERT INTO secure_schema.user_details VALUES(2,'alice',37,'alice@example.com','testpass');

GRANT USAGE ON SCHEMA secure_schema TO analyst_ro;

--Grant read permissions on specific columns only.

GRANT SELECT (id, name, age) ON secure_schema.user_details TO analyst_ro;

--User: "analyst_ro"

SELECT * FROM secure_schema.user_details;
ERROR:  permission denied for table user_details

SELECT name, age, password FROM secure_schema.user_details;
ERROR:  permission denied for table user_details

SELECT id, name,age FROM secure_schema.user_details;
 id | name  | age
----+-------+----
  1 | jack  |  34
  2 | alice |  37

Si incluyes las columnas restringidas en la sentencia SELECT o ingresas SELECT *, aparecerá un mensaje de error. Cloud SQL protege la PII de Josué y Alicia en estas columnas.

También puedes usar una sola sentencia GRANT para combinar diferentes privilegios.

GRANT SELECT (id,name,age), UPDATE (name) ON secure_schema.user_details TO analyst_ro;

Enfoque basado en vistas

Para lograr seguridad a nivel de la columna, también puedes crear una vista en una tabla, excluir o enmascarar las columnas que deseas ocultar de otros usuarios y proporcionar acceso a la vista en lugar de a la tabla.

En el siguiente ejemplo, se muestra cómo usar un enfoque basado en vistas para el sitio web de venta minorista para proteger la PII para Josué y Alicia:

--User: "admin"

CREATE SCHEMA analyst_ro;
CREATE VIEW analyst_ro.user_details AS SELECT id, name, age FROM secure_schema.user_details;
GRANT USAGE ON SCHEMA analyst_ro TO analyst_ro;
GRANT SELECT ON analyst_ro.user_details TO analyst_ro;

--User: "analyst_ro"

SELECT id,name,age FROM user_details;
 id | name  | age
----+-------+----
  1 | jack  |  34
  2 | alice |  37

SELECT * FROM user_details;
 id | name  | age
----+-------+----
  1 | jack  |  34
  2 | alice |  37

En este ejemplo, se crea un esquema separado para que la vista mantenga su mismo nombre que la tabla. Con el enfoque basado en vistas, puedes usar SELECT *.

También puedes crear una vista y enmascarar las columnas de la tabla de la base de datos para que los usuarios sin privilegios no puedan ver la PII que está enmascarada.

CREATE VIEW analyst_ro.user_details AS SELECT id, name, age, 'redacted@example.com' as email_id,'*****'::text as password FROM secure_schema.user_details;

SELECT * FROM user_details;
 id | name  | age |     email_id         | password
----+-------+-----+----------------------+---------
  1 | jack  |  34 | redacted@example.com | *****
  2 | alice |  37 | redacted@example.com | *****

Seguridad a nivel de la fila

La seguridad a nivel de las columnas y un enfoque basado en vistas te permiten ocultar la PII en columnas de tablas de bases de datos de usuarios específicos. Sin embargo, a veces querrás filtrar estos datos y otorgar acceso a filas específicas de una tabla. Esta tabla contiene la PII a la que solo pueden acceder algunos usuarios, según las condiciones de usuario aptas. Esto se conoce como seguridad a nivel de la fila.

La seguridad a nivel de la fila es útil para aplicaciones multiusuario en las que los usuarios tienen privilegios de acceso de lectura y escritura solo para su propia PII. En Cloud SQL, las tablas pueden tener políticas de seguridad a nivel de la fila que restringen por usuario, las filas que los usuarios pueden ver a través de consultas o las que pueden insertar, actualizar o borrar ejecutando comandos de modificación de datos.

Para el ejemplo del sitio web de venta minorista, puedes implementar la seguridad a nivel de la fila para Josué y Alicia, de modo que puedan ver su propia PII, pero no puedan modificarla ni borrarla.

--User: "admin"
--Create and enable a policy for row-level security

CREATE POLICY user_details_rls_pol ON secure_schema.user_details FOR ALL TO PUBLIC USING (name=current_user);
ALTER TABLE secure_schema.user_details ENABLE ROW LEVEL SECURITY;

SELECT * FROM secure_schema.user_details;
 id | name  | age |     email_id      | password
----+-------+-----+-------------------+---------
  1 | jack  |  34 | jack@example.com  | testpass
  2 | alice |  37 | alice@example.com | testpass

--User: "jack"

SELECT * FROM secure_schema.user_details;
 id | name | age |    email_id      | password
----+------+-----+------------------+---------
  1 | jack |  34 | jack@example.com | testpass

--User: "alice"

SELECT * FROM secure_schema.user_details;
 id | name  | age |    email_id       | password
----+-------+-----+-------------------+---------
  2 | alice |  37 | alice@example.com | testpass

Los usuarios a los que se les asignan roles con el atributo BYPASSRLS pueden omitir la seguridad a nivel de la fila cuando acceden a una tabla. Los propietarios de tablas también pueden omitir la seguridad a nivel de la fila. Si deseas someter al propietario de una tabla a la seguridad a nivel de la fila, usa el comando ALTER TABLE ... FORCE ROW LEVEL SECURITY.

A veces, no deseas aplicar la seguridad a nivel de la fila a las filas de una tabla de base de datos. Por ejemplo, si usas pg_dump para hacer una copia de seguridad de la tabla, no se recomienda omitir ninguna fila en la copia de seguridad. Para evitar que esto suceda, para el usuario que realiza la copia de seguridad, establece el parámetro de configuración row_security en OFF. Si se filtran filas según la seguridad a nivel de la fila, aparecerá un mensaje de error.

Enmascara y anonimiza datos

Además de enmascarar datos usando un enfoque basado en vistas, puedes enmascarar datos con la extensión postgresql_anonymizer. Esta extensión enmascara o reemplaza la PII o los datos sensibles desde una base de datos de PostgreSQL.

Usar la extensión en un enfoque basado en vistas te brinda los siguientes beneficios:

  • Tienes varias funciones de enmascaramiento, como la sustitución, la aleatorización, la falsificación, la seudonimización, la combinación parcial, la redistribución, la adición de ruido y la generalización.

  • Puedes generar datos enmascarados significativos que puedes usar para pruebas funcionales y procesamiento de datos.

  • Puedes usar el lenguaje de definición de datos (DDL) de PostgreSQL para declarar reglas de enmascaramiento y especificar la estrategia de anonimización dentro de la definición de la tabla.

Instala y configura la extensión postgresql_anonymizer

Para usar esta extensión en una instancia de Cloud SQL, completa los siguientes pasos:

  1. Edita la instancia y, luego, establece cloudsql.enable_anon flag en on: Si deseas obtener información para configurar marcas y revisar las marcas compatibles con la extensión, consulta Configura marcas de base de datos.

  2. Para crear la extensión en la base de datos, ejecuta el siguiente comando:

    --Connect to the PostgreSQL database
    
    CREATE EXTENSION IF NOT EXISTS anon CASCADE;
    SELECT anon.init();
    

Después de instalar y configurar la extensión, úsala en la instancia para implementar las estrategias de anonimización máscara dinámica, máscara estática y volcado anónimo.

Máscara dinámica

Usa máscaras dinámicas para definir reglas de enmascaramiento para usuarios específicos. Estos usuarios no pueden ver la PII. En su lugar, ven datos enmascarados. Todos los demás usuarios ven los datos sin enmascarar. Esto es útil en entornos de producción cuando no deseas alterar la PII, sino solo ocultarla de ciertos usuarios.

Para el ejemplo del sitio web de venta minorista, puedes implementar máscaras dinámicas para que el administrador pueda ver las direcciones de correo electrónico y las contraseñas sin enmascarar de Josué y Alicia, pero el analista solo puede ver los datos enmascarados.

--Activate the dynamic masking engine

SELECT anon.start_dynamic_masking();

--Declare the masking user and masking rules
--analyst_ro is the masked user with select privileges on the
--user_details table

SECURITY LABEL FOR anon ON ROLE analyst_ro IS 'MASKED';

SECURITY LABEL FOR anon ON COLUMN secure_schema.user_details.email_id IS 'MASKED WITH FUNCTION anon.fake_email()';
SECURITY LABEL FOR anon ON COLUMN secure_schema.user_details.password  IS 'MASKED WITH FUNCTION anon.hash(password)';

--User: "admin" (can see all unmasked data)

SELECT * FROM secure_schema.user_details;
 id | name  | age |    email_id       | password
----+-------+-----+------------  -----+---------
  1 | jack  |  34 | jack@example.com  | testpass
  2 | alice |  37 | alice@example.com | testpass

--User:"analyst_ro" (note that the "email_id" and "password" columns are
--replaced with masked data,)
--Data in the password column is truncated for better formatting.

SELECT * FROM secure_schema.user_details;
 id | name  | age |       email_id         | password
----+-------+-----+-----------------  -----+----------------
  1 | jack  |  34 | alisontodd@example.com | 13d249f2cb4127b
  2 | alice |  37 | amanda35@example.com   | 13d249f2cb4127b

Máscara estática

Usa máscaras estáticas para quitar la PII de una tabla, según los criterios definidos en las reglas de enmascaramiento y reemplazar esta información por los datos enmascarados. Los usuarios no pueden recuperar los datos sin enmascarar. Esto es útil en entornos de pruebas cuando deseas alterar la PII y no deseas que ningún usuario vea esta información.

Para el ejemplo del sitio web de venta minorista, puedes implementar máscaras estáticas para que ningún usuario pueda ver las direcciones de correo electrónico y las contraseñas sin enmascarar de Josué y Alicia. En su lugar, solo ven datos enmascarados.

--User: "admin"

SELECT * FROM secure_schema.user_details;
 id | name  | age |    email_id       | password
----+-------+-----+--------------  ---+---------
  1 | jack  |  34 | jack@example.com  | testpass
  2 | alice |  37 | alice@example.com | testpass

--Apply earlier defined masking rules to the table permanently.
--Now all users see masked data only.

SELECT anon.anonymize_table('secure_schema.user_details');
 anonymize_table
-----------------
 t

--User: "analyst_ro"
--Data in the password column is truncated for better formatting.

select * from secure_schema.user_details;
 id | name  | age |           email_id              |  password
----+-------+-----+-------------------------  ------+---------------
  1 | jack  |  34 | christophercampbell@example.com | 13d249f2cb412c
  2 | alice |  37 | annebenitez@example.com         | 13d249f2cb4127

Volcado anónimo

Usa volcados anónimos para exportar datos enmascarados a un archivo SQL. Para el ejemplo del sitio web de venta minorista, puedes crear un archivo de volcado para los datos enmascarados que se encuentran en la tabla user_details.

--Launch pg_dump_anon with the masked user to apply earlier defined --masking rules

pg_dump_anon -h HOSTIP -p 5432 -d DATABASE_NAME -U analyst_ro --table=secure_schema.user_details --file=user_details_anonysms.sql

Encripta datos

Aunque puedes enmascarar PII, la información se almacena en la base de datos como texto sin formato. Un administrador puede ver esta información.

Usa la extensión pgcrypto para encriptar la PII antes de almacenarla. De esta manera, solo los usuarios que tengan una clave de encriptación válida podrán desencriptar la información y verla como texto sin formato.

La extensión pgcrypto tiene varias funciones de hash y encriptación.

Hash

Un hash es una función criptográfica unidireccional en la que solo te interesa encriptar la PII. Esto es útil para almacenar las contraseñas en un formato con hash y hacer coincidir las contraseñas ingresadas por el usuario con las contraseñas con hash. Las contraseñas con hash nunca se desencriptan en texto sin formato.

Para el ejemplo del sitio web de venta minorista, puedes usar la extensión pgcrypto para generar un hash de la contraseña de Josué antes de almacenarla en la tabla de user_details.

--Hash passwords before storing them in the user_details table.

TRUNCATE TABLE secure_schema.user_details;
INSERT INTO secure_schema.user_details VALUES(1,'jack',34,'jack@example.com',crypt('testpassword', gen_salt('bf')));

--Match the hashed data with user entered password

SELECT id, name FROM secure_schema.user_details WHERE email_id = 'jack@example.com' AND password = crypt('testpassword', password);
 id | name
----+-----
  1 | jack

Encrypt

Usa una función criptográfica de encriptación para encriptar la PII con una clave. Luego, los usuarios necesitan esta clave para desencriptar la información en texto sin formato. Esto es útil para almacenar información de tarjetas de crédito y detalles bancarios en los que las aplicaciones desean recuperar la PII en un formato legible.

Para el ejemplo del sitio web de venta minorista, la contraseña y la dirección de correo electrónico de Josué están encriptadas. Los usuarios que tengan la clave de encriptación pueden desencriptar esta información y verla como texto sin formato. Para todos los demás usuarios, aparecerá un mensaje de error.

--"user_acc_key" is the encryption key

TRUNCATE TABLE secure_schema.user_details;
INSERT INTO secure_schema.user_details VALUES(1,'jack',34,pgp_sym_encrypt('jack@example.com','user_acc_key'),pgp_sym_encrypt('testpassword','user_acc_key'));

--User: "admin" (queries without an encryption key)
--Data in the email_id and password columns are truncated for better
--formatting.

SELECT * FROM secure_schema.user_details;
 id | name  | age |    email_id     | password
----+-------+-----+-----------------+-------------------
  1 | jack |  34 | \xc30d0407030209 | \xc30d040703028962

--User: "app_user" (queries with a valid encryption key)

SELECT name,pgp_sym_decrypt(email_id::bytea,'user_acc_key'),pgp_sym_decrypt(password::bytea,'user_acc_key') FROM secure_schema.user_details;
 name | pgp_sym_decrypt   | pgp_sym_decrypt
------+-------------------+----------------
 jack | jack@example.com  | testpassword

--If a user uses the wrong encryption key, then the following error message appears:

SELECT name,pgp_sym_decrypt(email_id::bytea,'user_bad_key'),
pgp_sym_decrypt(password::bytea,'user_bad_key') FROM secure_schema.user_details;
ERROR:  Wrong key or corrupt data

Próximos pasos

Obtén información sobre los siguientes controles adicionales que puedes usar para proteger la PII del acceso no garantizado: