La privacidad de los datos consiste en proteger datos, como la información personal identificable (IPI), de las personas que no deberían tener acceso a ellos. En esta página se describen varios enfoques de privacidad de los datos que puedes usar para proteger tu información personal identificable (IPI) en Cloud SQL.
Puedes usar Cloud SQL para almacenar tu información personal identificable de forma segura. Quieres asegurarte de que esta información se trata con la máxima protección de la privacidad para que no se pueda acceder a ella por error. Por ejemplo, si almacenas información de tarjetas de crédito o datos sanitarios en tus bases de datos, puedes usar Cloud SQL para ocultar o enmascarar la información personal identificable a los usuarios sin privilegios.
Sigue estas estrategias para proteger tu IPI en Cloud SQL:
- Seguridad a nivel de columna
- Estrategia basada en las vistas
- Seguridad a nivel de fila
- Máscara y anonimización de datos
- Cifrar datos
Seguridad a nivel de columna
La seguridad a nivel de columna te permite restringir quién puede ver el contenido de columnas específicas de las tablas de la base de datos. Los privilegios a nivel de columna se aplican a las instrucciones INSERT
, UPDATE
, SELECT
y REFERENCES
.
Por ejemplo, supongamos que tienes un sitio web de comercio en el que quieres controlar la información personal identificable de dos usuarios: Juan 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 incluye las columnas restringidas en la instrucción SELECT
o introduce SELECT *
, aparecerá un mensaje de error. Cloud SQL protege la información personal identificable de Jack y Alice en estas columnas.
También puedes usar una sola instrucción GRANT
para combinar diferentes privilegios.
GRANT SELECT (id,name,age), UPDATE (name) ON secure_schema.user_details TO analyst_ro;
Enfoque basado en las visualizaciones
También puedes conseguir seguridad a nivel de columna creando una vista en una tabla, excluyendo o enmascarando las columnas que quieras ocultar a otros usuarios y proporcionando acceso a la vista en lugar de a la tabla.
En el siguiente ejemplo se muestra cómo usar un enfoque basado en vistas en el sitio web de una tienda para proteger la información personal identificable de Juan y Ana:
--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 independiente para la vista, de modo que su nombre sea el mismo que el de la tabla. Con el enfoque basado en vistas, puedes usar SELECT *
.
También puede 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 información personal identificable 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 fila
La seguridad a nivel de columna y un enfoque basado en vistas te permiten ocultar la información personal identificable de las columnas de las tablas de bases de datos a usuarios específicos. Sin embargo, a veces querrá filtrar estos datos y conceder acceso a filas específicas de una tabla. Esta tabla contiene información personal identificable a la que solo pueden acceder determinados usuarios en función de las condiciones de usuario que cumplan. Esto se conoce como seguridad a nivel de fila.
La seguridad a nivel de fila es útil en aplicaciones multiinquilino en las que los usuarios tienen privilegios de acceso de lectura y escritura solo a su propia información personal. En Cloud SQL, las tablas pueden tener políticas de seguridad a nivel de fila que restrinjan, por usuario, las filas que los usuarios pueden ver al crear consultas o las filas que pueden insertar, actualizar o eliminar al ejecutar comandos de modificación de datos.
En el ejemplo del sitio web de comercio, puedes implementar la seguridad a nivel de fila para Jack y Alice de forma que puedan ver su información personal, pero no modificarla ni eliminarla.
--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 que tienen el atributo BYPASSRLS
pueden saltarse la seguridad a nivel de fila cuando acceden a una tabla. Los propietarios de las tablas también pueden omitir la seguridad a nivel de fila. Si quieres aplicar la seguridad a nivel de fila a un propietario de una tabla, usa el comando ALTER TABLE ... FORCE ROW LEVEL SECURITY
.
A veces, no quieres aplicar la seguridad a nivel de fila a las filas de una tabla de una base de datos. Por ejemplo, si usas pg_dump para crear una copia de seguridad de la tabla, no querrás que se omita ninguna fila de la copia de seguridad. Para evitar que esto ocurra, asigna el valor OFF
al parámetro de configuración row_security
del usuario que realiza la copia de seguridad. Si se filtra alguna fila en función de la seguridad a nivel de fila, se mostrará un mensaje de error.
Enmascarar y anonimizar datos
Además de enmascarar datos mediante un enfoque basado en vistas, puede enmascarar datos con la extensión postgresql_anonymizer
. Esta extensión enmascara o sustituye la información personal identificable o los datos sensibles desde el punto de vista comercial de una base de datos PostgreSQL.
Usar la extensión en lugar de un enfoque basado en vistas le ofrece las siguientes ventajas:
Tienes varias funciones de enmascaramiento, como sustitución, aleatorización, falsificación, seudonimización, cifrado parcial, barajado, adición de ruido y generalización.
Puedes generar datos enmascarados significativos que puedes usar para pruebas funcionales y procesamiento de datos.
Puede usar el lenguaje de definición de datos (DDL) de PostgreSQL para declarar reglas de enmascaramiento y especificar la estrategia de anonimización en la definición de la tabla.
Instalar y configurar la extensión postgresql_anonymizer
Para usar esta extensión en una instancia de Cloud SQL, sigue estos pasos:
Edita la instancia y, a continuación, cambia el valor de
cloudsql.enable_anon flag
aon
. Para obtener información sobre cómo definir marcas y consultar las marcas admitidas por la extensión, consulta Configurar marcas de bases de datos.Crea la extensión en la base de datos ejecutando 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 información personal identificable. En su lugar, ven datos enmascarados. Todos los demás usuarios verán los datos sin enmascarar. Esto resulta útil en entornos de producción cuando no quieres modificar la información personal, sino solo ocultarla a determinados usuarios.
En el ejemplo del sitio web de una tienda, puede implementar máscaras dinámicas para que el administrador pueda ver las direcciones de correo y las contraseñas sin enmascarar de Jack y Alice, pero el analista solo pueda 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 eliminar la IPI de una tabla según los criterios definidos en las reglas de enmascaramiento y sustituir esta información por datos enmascarados. Los usuarios no pueden recuperar los datos sin máscara. Esto resulta útil en entornos de prueba cuando quieres modificar la información personal identificable y no quieres que ningún usuario vea esta información.
En el ejemplo del sitio web de comercio, puedes implementar máscaras estáticas para que ningún usuario pueda ver las direcciones de correo y las contraseñas sin enmascarar de Jack y Alice. 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 anonimizados a un archivo SQL. En el ejemplo del sitio web de comercio, puede crear un archivo de volcado de los datos anonimizados 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
Cifrar datos
Aunque puedes enmascarar la IPI, 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 cifrar la información personal identificable antes de almacenarla. De esta forma, solo los usuarios que tengan una clave de cifrado válida podrán descifrar la información y verla como texto sin formato.
La extensión pgcrypto
tiene varias funciones de hash y cifrado.
Hash
Un hash es una función criptográfica unidireccional en la que solo te interesa cifrar la IPI. Esto resulta útil para almacenar contraseñas en formato cifrado con hash y para comparar las contraseñas introducidas por los usuarios con las contraseñas cifradas con hash. Las contraseñas cifradas nunca se descifran en texto sin formato.
En el ejemplo del sitio web de comercio, puedes usar la extensión pgcrypto
para cifrar con hash la contraseña de Jack antes de almacenarla en la tabla 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
Cifrar
Usa una función criptográfica de cifrado para cifrar la información personal identificable con una clave. Los usuarios necesitan esta clave para descifrar la información y convertirla en texto sin formato. Esto resulta útil para almacenar información de tarjetas de crédito y datos bancarios en los casos en los que las aplicaciones quieran recuperar la IPI en un formato legible.
En el ejemplo del sitio web de venta, la contraseña y la dirección de correo de Jack están cifradas. Los usuarios que tengan la clave de cifrado podrán descifrar esta información y verla como texto sin formato. Para el resto de los usuarios, aparece 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
Siguientes pasos
Consulta los siguientes controles adicionales que puedes usar para proteger la información personal identificable frente a accesos no autorizados: