-- Create application users with minimal privilegesCREATEUSERapp_userWITHPASSWORD'strong_password_here';CREATEUSERreadonly_userWITHPASSWORD'readonly_password_here';CREATEUSERbackup_userWITHPASSWORD'backup_password_here';-- Grant specific privilegesGRANTCONNECTONDATABASEproductionTOapp_user;GRANTUSAGEONSCHEMApublicTOapp_user;GRANTSELECT,INSERT,UPDATE,DELETEONALLTABLESINSCHEMApublicTOapp_user;GRANTUSAGE,SELECTONALLSEQUENCESINSCHEMApublicTOapp_user;-- Read-only userGRANTCONNECTONDATABASEproductionTOreadonly_user;GRANTUSAGEONSCHEMApublicTOreadonly_user;GRANTSELECTONALLTABLESINSCHEMApublicTOreadonly_user;-- Backup userGRANTCONNECTONDATABASEproductionTObackup_user;GRANTUSAGEONSCHEMApublicTObackup_user;GRANTSELECTONALLTABLESINSCHEMApublicTObackup_user;-- Set default privileges for future objectsALTERDEFAULTPRIVILEGESINSCHEMApublicGRANTSELECT,INSERT,UPDATE,DELETEONTABLESTOapp_user;ALTERDEFAULTPRIVILEGESINSCHEMApublicGRANTUSAGE,SELECTONSEQUENCESTOapp_user;ALTERDEFAULTPRIVILEGESINSCHEMApublicGRANTSELECTONTABLESTOreadonly_user;
-- Create roles for different access levelsCREATEROLEapp_developer;CREATEROLEapp_readonly;CREATEROLEapp_admin;CREATEROLEdb_maintenance;-- Grant role privilegesGRANTCONNECTONDATABASEproductionTOapp_developer;GRANTUSAGEONSCHEMApublicTOapp_developer;GRANTSELECT,INSERT,UPDATE,DELETEONALLTABLESINSCHEMApublicTOapp_developer;GRANTUSAGE,SELECTONALLSEQUENCESINSCHEMApublicTOapp_developer;GRANTCONNECTONDATABASEproductionTOapp_readonly;GRANTUSAGEONSCHEMApublicTOapp_readonly;GRANTSELECTONALLTABLESINSCHEMApublicTOapp_readonly;GRANTALLPRIVILEGESONDATABASEproductionTOapp_admin;GRANTALLPRIVILEGESONSCHEMApublicTOapp_admin;-- Grant maintenance privilegesGRANTCONNECTONDATABASEproductionTOdb_maintenance;GRANTUSAGEONSCHEMApublicTOdb_maintenance;GRANTSELECTONALLTABLESINSCHEMApublicTOdb_maintenance;-- Assign users to rolesGRANTapp_developerTOapp_user;GRANTapp_readonlyTOreadonly_user;GRANTapp_adminTOadmin_user;GRANTdb_maintenanceTObackup_user;
-- Enable RLS on sensitive tablesALTERTABLEusersENABLEROWLEVELSECURITY;ALTERTABLEpostsENABLEROWLEVELSECURITY;ALTERTABLEfinancial_dataENABLEROWLEVELSECURITY;-- Create policies for user data accessCREATEPOLICYuser_own_dataONusersFORALLTOapp_userUSING(id=current_setting('app.current_user_id')::integer);CREATEPOLICYuser_own_postsONpostsFORALLTOapp_userUSING(user_id=current_setting('app.current_user_id')::integer);-- Policy for financial data (admin only)CREATEPOLICYadmin_financial_accessONfinancial_dataFORALLTOapp_adminUSING(true);-- Policy for read-only accessCREATEPOLICYreadonly_accessONpostsFORSELECTTOapp_readonlyUSING(published=true);
# encryption/field_encryption.pyimportpsycopg2fromcryptography.fernetimportFernetimportbase64importosclassPostgreSQLFieldEncryption:def__init__(self,encryption_key=None):ifencryption_key:self.cipher=Fernet(encryption_key)else:# Generate new keykey=Fernet.generate_key()self.cipher=Fernet(key)print(f"Generated encryption key: {key.decode()}")defencrypt_field(self,value):"""Encrypt a field value."""ifvalueisNone:returnNoneencrypted=self.cipher.encrypt(value.encode())returnbase64.b64encode(encrypted).decode()defdecrypt_field(self,encrypted_value):"""Decrypt a field value."""ifencrypted_valueisNone:returnNonetry:encrypted=base64.b64decode(encrypted_value.encode())decrypted=self.cipher.decrypt(encrypted)returndecrypted.decode()exceptExceptionase:print(f"Decryption error: {e}")returnNonedefcreate_encrypted_table(self,connection):"""Create table with encrypted fields."""withconnection.cursor()ascur:cur.execute(""" CREATE TABLE IF NOT EXISTS encrypted_users ( id SERIAL PRIMARY KEY, username VARCHAR(50), email VARCHAR(100), encrypted_ssn TEXT, encrypted_credit_card TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); """)connection.commit()definsert_encrypted_data(self,connection,username,email,ssn,credit_card):"""Insert data with encrypted fields."""encrypted_ssn=self.encrypt_field(ssn)encrypted_credit_card=self.encrypt_field(credit_card)withconnection.cursor()ascur:cur.execute(""" INSERT INTO encrypted_users (username, email, encrypted_ssn, encrypted_credit_card) VALUES (%s, %s, %s, %s) """,(username,email,encrypted_ssn,encrypted_credit_card))connection.commit()defretrieve_encrypted_data(self,connection,user_id):"""Retrieve and decrypt data."""withconnection.cursor()ascur:cur.execute(""" SELECT id, username, email, encrypted_ssn, encrypted_credit_card FROM encrypted_users WHERE id = %s """,(user_id,))row=cur.fetchone()ifrow:return{'id':row[0],'username':row[1],'email':row[2],'ssn':self.decrypt_field(row[3]),'credit_card':self.decrypt_field(row[4])}returnNone# Usageencryption=PostgreSQLFieldEncryption()conn=psycopg2.connect(host='localhost',database='production',user='app_user',password='app_password')encryption.create_encrypted_table(conn)encryption.insert_encrypted_data(conn,'user1','user1@example.com','123-45-6789','4111-1111-1111-1111')user_data=encryption.retrieve_encrypted_data(conn,1)print(user_data)
# monitoring/security_monitor.pyimportpsycopg2importjsonimporttimefromdatetimeimportdatetime,timedeltaimportsmtplibfromemail.mime.textimportMIMETextclassPostgreSQLSecurityMonitor:def__init__(self,connection_params,alert_config):self.conn_params=connection_paramsself.alert_config=alert_configself.conn=Nonedefconnect(self):"""Connect to PostgreSQL."""self.conn=psycopg2.connect(**self.conn_params)defcheck_failed_logins(self,hours=1):"""Check for failed login attempts."""withself.conn.cursor()ascur:cur.execute(""" SELECT usename, client_addr, application_name, count(*) as failed_attempts FROM pg_stat_activity WHERE state = 'idle in transaction (aborted)' AND query_start > NOW() - INTERVAL '%s hours' GROUP BY usename, client_addr, application_name HAVING count(*) > 5 ORDER BY failed_attempts DESC; """,(hours,))returncur.fetchall()defcheck_privilege_escalation(self):"""Check for privilege escalation attempts."""withself.conn.cursor()ascur:cur.execute(""" SELECT usename, client_addr, application_name, query FROM pg_stat_activity WHERE query ILIKE '%GRANT%' OR query ILIKE '%REVOKE%' OR query ILIKE '%ALTER USER%' OR query ILIKE '%CREATE USER%' ORDER BY query_start DESC; """)returncur.fetchall()defcheck_suspicious_queries(self):"""Check for suspicious query patterns."""withself.conn.cursor()ascur:cur.execute(""" SELECT usename, client_addr, application_name, query, query_start FROM pg_stat_activity WHERE query ILIKE '%DROP%' OR query ILIKE '%TRUNCATE%' OR query ILIKE '%DELETE FROM%' OR query ILIKE '%UPDATE%' ORDER BY query_start DESC; """)returncur.fetchall()defcheck_audit_log_anomalies(self,hours=24):"""Check audit log for anomalies."""withself.conn.cursor()ascur:cur.execute(""" SELECT changed_by, client_ip, application_name, count(*) as operations FROM audit.audit_log WHERE changed_at > NOW() - INTERVAL '%s hours' GROUP BY changed_by, client_ip, application_name HAVING count(*) > 100 ORDER BY operations DESC; """,(hours,))returncur.fetchall()defsend_security_alert(self,subject,message):"""Send security alert via email."""try:msg=MIMEText(message)msg['Subject']=subjectmsg['From']=self.alert_config['from_email']msg['To']=self.alert_config['to_email']server=smtplib.SMTP(self.alert_config['smtp_server'],self.alert_config['smtp_port'])server.starttls()server.login(self.alert_config['username'],self.alert_config['password'])server.send_message(msg)server.quit()print(f"Security alert sent: {subject}")exceptExceptionase:print(f"Failed to send alert: {e}")defrun_security_checks(self):"""Run all security checks."""alerts=[]# Check failed loginsfailed_logins=self.check_failed_logins()iffailed_logins:alerts.append({'type':'failed_logins','message':f"Multiple failed login attempts detected: {failed_logins}",'severity':'high'})# Check privilege escalationprivilege_attempts=self.check_privilege_escalation()ifprivilege_attempts:alerts.append({'type':'privilege_escalation','message':f"Privilege escalation attempts detected: {privilege_attempts}",'severity':'critical'})# Check suspicious queriessuspicious_queries=self.check_suspicious_queries()ifsuspicious_queries:alerts.append({'type':'suspicious_queries','message':f"Suspicious queries detected: {suspicious_queries}",'severity':'medium'})# Send alertsforalertinalerts:self.send_security_alert(f"PostgreSQL Security Alert: {alert['type']}",alert['message'])returnalerts# Usageif__name__=="__main__":monitor=PostgreSQLSecurityMonitor(connection_params={'host':'localhost','database':'production','user':'security_monitor','password':'monitor_password'},alert_config={'from_email':'alerts@company.com','to_email':'security@company.com','smtp_server':'smtp.company.com','smtp_port':587,'username':'alerts@company.com','password':'smtp_password'})monitor.connect()alerts=monitor.run_security_checks()print(f"Security check completed. {len(alerts)} alerts generated.")
# anonymization/data_anonymizer.pyimportpsycopg2importrandomimportstringfromfakerimportFakerclassPostgreSQLDataAnonymizer:def__init__(self,connection_params):self.conn_params=connection_paramsself.fake=Faker()self.conn=Nonedefconnect(self):"""Connect to PostgreSQL."""self.conn=psycopg2.connect(**self.conn_params)defanonymize_users(self):"""Anonymize user data."""withself.conn.cursor()ascur:# Get all userscur.execute("SELECT id, username, email FROM users")users=cur.fetchall()foruser_id,username,emailinusers:# Generate fake datafake_username=self.fake.user_name()fake_email=self.fake.email()# Update user datacur.execute(""" UPDATE users SET username = %s, email = %s WHERE id = %s """,(fake_username,fake_email,user_id))self.conn.commit()print(f"Anonymized {len(users)} users")defanonymize_posts(self):"""Anonymize post content."""withself.conn.cursor()ascur:# Get all postscur.execute("SELECT id, title, content FROM posts")posts=cur.fetchall()forpost_id,title,contentinposts:# Generate fake contentfake_title=self.fake.sentence(nb_words=6)fake_content=self.fake.text(max_nb_chars=500)# Update post datacur.execute(""" UPDATE posts SET title = %s, content = %s WHERE id = %s """,(fake_title,fake_content,post_id))self.conn.commit()print(f"Anonymized {len(posts)} posts")defcreate_anonymized_copy(self,source_db,target_db):"""Create anonymized copy of database."""withself.conn.cursor()ascur:# Create target databasecur.execute(f"CREATE DATABASE {target_db}")self.conn.commit()# Connect to target databasetarget_conn=psycopg2.connect(host=self.conn_params['host'],database=target_db,user=self.conn_params['user'],password=self.conn_params['password'])withtarget_conn.cursor()ascur:# Copy schemacur.execute(f"CREATE SCHEMA IF NOT EXISTS public")# Copy tables structurecur.execute(""" SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' """)tables=cur.fetchall()fortable_name,intables:# Create table in target databasecur.execute(f"CREATE TABLE {table_name} (LIKE {source_db}.{table_name})")target_conn.commit()target_conn.close()print(f"Created anonymized copy: {target_db}")# Usageif__name__=="__main__":anonymizer=PostgreSQLDataAnonymizer({'host':'localhost','database':'production','user':'anonymizer','password':'anonymizer_password'})anonymizer.connect()anonymizer.anonymize_users()anonymizer.anonymize_posts()anonymizer.create_anonymized_copy('production','production_anonymized')