
{"id":7086,"date":"2022-10-22T17:18:13","date_gmt":"2022-10-22T17:18:13","guid":{"rendered":"https:\/\/rax-stg-wp-aws.com\/blogs\/security-on-postgresql-and-rds\/"},"modified":"2026-11-03T19:27:49","modified_gmt":"2026-11-03T19:27:49","slug":"security-on-postgresql-and-rds","status":"publish","type":"blogs","link":"https:\/\/www.rackspace.com\/en-gb\/blogs\/security-on-postgresql-and-rds\/","title":{"rendered":"Security on PostgreSQL and RDS"},"content":{"rendered":"<p>This blog describes how to set up the security in PostgreSQL and AWS Aurora and related best practices. The Database security refers to a set of procedures and policies that safeguard data. It becomes crucial to understand its significance.<\/p>\n<p>\n<strong>Important Components<\/strong><br \/>\nLet us look at the important components around the same:<\/p>\n<ul>\n<li>Host-based authentication (HBA) Authentication, privilege of a role\/group\/user (Authorization)<\/li>\n<li>Different Levels of Security<\/li>\n<li>pg_hba.conf file supports multiple methods of authentication<\/li>\n<li>Password authentication<\/li>\n<li>Ident authentication<\/li>\n<li>Trust authentication<\/li>\n<li>PAM authentication<\/li>\n<li>LDAP authentication<\/li>\n<li>SSPI authentication<\/li>\n<li>GSSAPI authentication<\/li>\n<li>Certificate authentication<\/li>\n<li>Peer authentication<\/li>\n<li>RADIUS authentication<\/li>\n<li>BSD authentication<\/li>\n<li>Row Level Security (RLS)<\/li>\n<li>Security Logging for RDS \/Aurora PostgreSQL<\/li>\n<\/ul>\n<p>&nbsp; &nbsp;&nbsp;<br \/>\n&nbsp;I.&nbsp;&nbsp; &nbsp;Default Logging<\/p>\n<p>II.&nbsp;&nbsp; &nbsp;DB Parameter Group<\/p>\n<p>III.&nbsp;&nbsp; &nbsp;Object-based Query Logging with the pgaudit extension<\/p>\n<p>IV.&nbsp;&nbsp; &nbsp;Publishing PostgreSQL Logs to CloudWatch Logs<\/p>\n<ul>\n<li>Object Ownership<\/li>\n<li>Application Access Parameters<\/li>\n<li>Protecting Against Injection Attacks with SQL\/Protect<\/li>\n<li>Source Code Protection for Functions<br \/>\n\t&nbsp;<\/li>\n<\/ul>\n<p><strong>Authentication and Authorization<\/strong><\/p>\n<p>Secure access is a two-stage (AA) process, and it ensures that only authorized users are logging into the Database with the assigned privileges.<\/p>\n<ul>\n<li><strong>Authentication:&nbsp;<\/strong>It ensures that a user is who he or she claims to.<\/li>\n<li><strong>Authorization:&nbsp;<\/strong>It allows the user access to DB resources based on the user\u2019s identity and the user has been granted the appropriate privileges.<\/li>\n<\/ul>\n<p><strong>Different Levels of Security<\/strong><\/p>\n<p><strong>The Postgres level of security is based on Network-level, Transport Level and Database level<\/strong><\/p>\n<ul>\n<li>Server and Application<\/li>\n<\/ul>\n<p>&nbsp; &nbsp; &nbsp;Check Client IP\/Authentication mode<br \/>\n&nbsp; &nbsp; &nbsp;<\/p>\n<p><em>&nbsp; &nbsp; &nbsp; Pg_hba.conf<\/em><\/p>\n<ul>\n<li>Database&nbsp;<\/li>\n<\/ul>\n<p>Role\/User\/Password<br \/>\nConnect Privilege<br \/>\nSchema Permission (usage, CRUD)<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp;<\/p>\n<ul>\n<li>Object&nbsp;<\/li>\n<\/ul>\n<p>Table Level Privilege\/execute privilege on the function&nbsp;<br \/>\nGrant\/Revoke<\/p>\n<p><strong>pg_hba.conf \u2013 Access Control<\/strong><\/p>\n<ul>\n<li>Host-based access control file (pg_hba.conf)<\/li>\n<li>Pg_hba.conf file is located in Cluster data directory<\/li>\n<li>Read at startup, any change requires to reload(using pg_reload_conf())<\/li>\n<li>Each record specify connection type, database name, user name , client IP and method of authentication(LDAP,TRUST,PAM)<\/li>\n<li>Top to bottom reading of a pg_hba file<\/li>\n<li>Hostnames, IPv6 and IPv4 supported with CIDR<\/li>\n<li>Authentication methods \u2013 password, trust, reject, md5, sspi , gss, , krb5,ident, peer, pam, ldap, radius or cert etc.<\/li>\n<\/ul>\n<p><strong>Row Level Security (RLS)<\/strong><\/p>\n<p><strong>RLS enables you to use group membership or execution context for controlling access to the rows in a database Table.<\/strong><\/p>\n<ul>\n<li>GRANT and REVOKE can be used at table level<\/li>\n<li>PostgreSQL &gt;9.5 supports security policies for limiting access at row level<\/li>\n<li>RLS offers stronger security as it is enforced by the database<\/li>\n<li>Security policies are controlled by DBA not by the application team<\/li>\n<li>All rows of a table are visible by default<\/li>\n<li>Once RLS is enabled on a table, all the queries must go through the security policy<\/li>\n<\/ul>\n<p>Example:<\/p>\n<p>To enable row-level security for the table:<\/p>\n<ul>\n<li>Create the table first and enable RLS on table<\/li>\n<\/ul>\n<p>&nbsp; &nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; <em>ALTER TABLE accounts ENABLE ROW LEVEL SECURITY;<\/em><\/p>\n<ul>\n<li>To create a policy on the table to allow the role to view the rows of their table, the CREATE POLICY command can be used.<\/li>\n<\/ul>\n<p>&nbsp; <em>CREATE POLICY policy_name ON table_name TO role_name USING(role = Current_user);<\/em><br \/>\n&nbsp; &nbsp; &nbsp;&nbsp;<br \/>\nNote: &nbsp;To allow all users to view their own row in a user table, a simple policy can be used:<\/p>\n<p><em>CREATE POLICY usr_policy ON users USING (user = current_user);<\/em><\/p>\n<p><strong>Security Logging for RDS \/Aurora PostgreSQL<\/strong><\/p>\n<p>PostgreSQL generates event logs that contain useful information for DBAs like SQL query issues, failed login, and dead locks are captured in the database by default. However, from a security perspective compliance and security groups are also interested in capturing addition database activity. For instance, successful logins and user queries for security monitoring and audit purposes.&nbsp;<\/p>\n<p><strong>Default Logging<\/strong><\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26250-body-Picture1_13.png\" alt=\"postgres pic 1\" \/><\/p>\n<p><strong>DB Parameter Group<\/strong><\/p>\n<p>Each RDS and Aurora PostgreSQL instances are associated with a parameter group that contains engine specific settings. The engine configurations also include several parameters that control the PostgreSQL logging behavior. AWS provides the parameter groups default configuration settings to use for your instance. To enable additional options the default settings for the parameters given in the following table must be changed to the recommended value.<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26250-body-Picture3_14.png\" alt=\"postgres pic 3\" \/><\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26250-body-Picture4_0.PNG\" alt=\"postgres pic 4\" \/><\/p>\n<p><strong>Object based query Logging with pgaudit extension<\/strong><\/p>\n<p>The following summaries show how to enable with pgaudit and provides, and example of configuring object level query auditing and table mytable.<\/p>\n<p><strong>Create specific database role called rds_pgaudit<\/strong><\/p>\n<p><em>CREATE ROLE rds_pgaudit;<\/em><\/p>\n<p>Modify the parameter group that is associated with your DB instance to use the shared preload libraries that contain pgaudit.role. (it needs to restart the DB instance)<\/p>\n<p><em>Pgaudit.role=rds_pgaudit<br \/>\nShared_preload_libraries=pgaudit<\/em><\/p>\n<p><strong>Run the following command to create the pgaudit extension<\/strong><\/p>\n<p><em>CREATE EXTENSION pgaudit;<\/em><\/p>\n<p><strong>To test the audit logging,run several commands that you have chosen to audit<\/strong><\/p>\n<p><em>CREATE TABLE mytable(id int);<\/em><br \/>\n<em>GRANT SELECT ON mytable to rds_pgaudit;<\/em><\/p>\n<p><strong>Publishing PostgreSQL Logs to CloudWatch Logs.<\/strong><\/p>\n<p>By default, PostgreSQL log records are stored in a DB instance for three days and a maximum of seven days. With CloudWatch logs, you can store PostgreSQL log records for much longer, and also perform real-time analysis of log data and use CloudWatch to view metrics and create alarms.<\/p>\n<p>To work with the CloudWatch logs, configure RDS for PostgreSQL instance to publish log data to a log group. You can Publish the following log types to CloudWatch logs for PostgreSQL<br \/>\nPostgreSQL log<br \/>\nUpgrade log (not available for Aurora PostgeSQL)<\/p>\n<p>\n<strong>To publish PostgreSQL logs to CloudWatch logs using the console:<\/strong><\/p>\n<ul>\n<li>Open the RDS console<\/li>\n<li>Choose the DB instance and select modify<\/li>\n<li>In the log exports section, choose the logs to start publishing to CloudWatch logs.<\/li>\n<li>Choose continue, and then choose to modify DB instance on the summary page.<\/li>\n<li>Select the log types to publish to Amazon Cloudwath Logs, PostgreSQL and Upgrade log<\/li>\n<\/ul>\n<p><strong>We can publish PostgreSQL logs with the AWS CLI. The following command will modify an existing DB instance:<\/strong><\/p>\n<p><em>AWS rds modify-db-instance \u2013db-instance-identifier mydbinstance &nbsp;&#8211;cloudwatch-logs-export-configuration \u2018{\u201cEnableLogTypes\u201d:[\u201cpostgresql\u201d,\u201dupgrade\u201d]}\u2019<\/em><\/p>\n<p>\nSimilar AWS CLI commands are available for publishing the logs to CloudWatch Logs when creating an instance or restoring an instance from a snapshot.<\/p>\n<p><strong>Application Access<\/strong><\/p>\n<p>&#8211; <strong>Application\/user access is controlled by settings in both (postgresql.conf ,pg_hba.conf)<\/strong><br \/>\n&#8211;&nbsp;<strong>Set the following parameters in postgresql.conf:<\/strong><\/p>\n<ul>\n<li>unix_socket_directory<\/li>\n<li>unix_socket_group<\/li>\n<li>unix_socket_permissions<\/li>\n<li>listen_addresses<\/li>\n<li>max_connections<\/li>\n<li>superuser_reserved_connections<\/li>\n<li>port<\/li>\n<\/ul>\n<p><strong>SQL Level Protect<\/strong><\/p>\n<ul>\n<li>To Protects Postgres databases from SQL injection attacks<\/li>\n<li>SQL Protect add a security layer managed by DBA<\/li>\n<li>We can add-on module delivered through Stack Builder<\/li>\n<\/ul>\n<p><strong><em>EDB*Wrap<\/em><\/strong><\/p>\n<p>EDB*Wrap utility converts the source code of database functions<\/p>\n<ul>\n<li>Everything is wrapped in obfuscated form like Oracle wrap capability<\/li>\n<\/ul>\n<p>\n<strong>Conclusion:<\/strong><\/p>\n<p>In this document, we have looked at the security of PostgreSQL\/RDS\/Aurora Postgres implementation and the factors related to server access, database access, database object access and row-level access.<br \/>\nWe have seen the best practices for securing access and adding entry and select authentication methods.<\/p>\n<p>Hopefully, this overview helps review the security of PostgreSQL.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Security on PostgreSQL and RDS<\/p>\n","protected":false},"author":2,"featured_media":7088,"menu_order":0,"comment_status":"open","ping_status":"open","template":"","format":"standard","meta":{"content-type":"","nid":"26250","content_type":"blog","created_by":"10130","authored_on":"2023-11-16T18:18:12+00:00","field_article_industries":"","tag_category":"Technical","field_blog_author_text":"by Amit Singh, Postgres Database Administrator, Rackspace Technology","seo_description":"Explore PostgreSQL and AWS Aurora security setup and best practices in this blog. Learn essential procedures and policies for safeguarding your data.","field_featured_image":"","insights_image":"\/wp-content\/uploads\/2026\/blog_technical_images\/26250-insights_image-security-technical-blog-1-insights.jpg","field_partners":"","rxt_platforms":"Big Data","product":"","publisheddate":"2022-10-22T17:18:13","rxt_solutions":"Data, Databases","opengraph_tag":"","x_tag":"","teaser_flag":"Technical Blog","seo_titile":"Security on PostgreSQL and RDS | Rackspace Technology","field_topics":"","field_slug":"security-on-postgresql-and-rds","footnotes":""},"categories":[178],"tags":[204],"class_list":["post-7086","blogs","type-blogs","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","tag-technical"],"_links":{"self":[{"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/blogs\/7086","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/blogs"}],"about":[{"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/types\/blogs"}],"author":[{"embeddable":true,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/comments?post=7086"}],"version-history":[{"count":2,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/blogs\/7086\/revisions"}],"predecessor-version":[{"id":8940,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/blogs\/7086\/revisions\/8940"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/media\/7088"}],"wp:attachment":[{"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/media?parent=7086"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/categories?post=7086"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/tags?post=7086"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}