From 1efa30c43f200fe5273d256e63d8a9534555c883 Mon Sep 17 00:00:00 2001 From: Long Hoang Date: Mon, 14 Nov 2022 12:43:13 +0800 Subject: [PATCH 01/36] Send exit surveys to new endpoint --- .../interfaces/Billing/ExitSurvey/ExitSurvey.tsx | 12 ++++-------- .../Billing/ExitSurvey/ExitSurvey.utils.ts | 11 ----------- .../DeleteProjectPanel/DeleteProjectButton.tsx | 9 ++++----- 3 files changed, 8 insertions(+), 24 deletions(-) delete mode 100644 studio/components/interfaces/Billing/ExitSurvey/ExitSurvey.utils.ts diff --git a/studio/components/interfaces/Billing/ExitSurvey/ExitSurvey.tsx b/studio/components/interfaces/Billing/ExitSurvey/ExitSurvey.tsx index 8a132af57f2..c1838f7c233 100644 --- a/studio/components/interfaces/Billing/ExitSurvey/ExitSurvey.tsx +++ b/studio/components/interfaces/Billing/ExitSurvey/ExitSurvey.tsx @@ -8,7 +8,6 @@ import { useStore } from 'hooks' import { post, patch } from 'lib/common/fetch' import { API_URL, PROJECT_STATUS } from 'lib/constants' import { CANCELLATION_REASONS } from '../Billing.constants' -import { generateFeedbackMessage } from './ExitSurvey.utils' import { UpdateSuccess } from '../' import { SubscriptionPreview } from '../Billing.types' import { StripeSubscription } from 'components/interfaces/Billing' @@ -138,14 +137,11 @@ const ExitSurvey: FC = ({ freeTier, subscription, onSelectBack }) => { setIsSuccessful(true) } } - - // Submit exit survey to Hubspot - const feedbackRes = await post(`${API_URL}/feedback/send`, { + const feedbackRes = await post(`${API_URL}/feedback/downgrade`, { projectRef, - subject: 'Subscription cancellation - Exit survey [Downgrade]', - tags: ['dashboard-exitsurvey'], - category: 'Billing', - message: generateFeedbackMessage(selectedReasons, downgradeMessage), + reasons: selectedReasons.reduce((a, b) => `${a}- ${b}\n`, ''), + additionalFeedback: downgradeMessage, + exitAction: 'downgrade', }) if (feedbackRes.error) throw feedbackRes.error } catch (error: any) { diff --git a/studio/components/interfaces/Billing/ExitSurvey/ExitSurvey.utils.ts b/studio/components/interfaces/Billing/ExitSurvey/ExitSurvey.utils.ts deleted file mode 100644 index c98250007a3..00000000000 --- a/studio/components/interfaces/Billing/ExitSurvey/ExitSurvey.utils.ts +++ /dev/null @@ -1,11 +0,0 @@ -export const generateFeedbackMessage = (reasons: string[], message: string) => { - return ` -Exit survey \n - -Reasons for leaving: -${reasons.reduce((a, b) => `${a}- ${b}\n`, '')} - -Additional feedback: -${message} - ` -} diff --git a/studio/components/interfaces/Settings/General/DeleteProjectPanel/DeleteProjectButton.tsx b/studio/components/interfaces/Settings/General/DeleteProjectPanel/DeleteProjectButton.tsx index 9ca011ac664..21873e761a1 100644 --- a/studio/components/interfaces/Settings/General/DeleteProjectPanel/DeleteProjectButton.tsx +++ b/studio/components/interfaces/Settings/General/DeleteProjectPanel/DeleteProjectButton.tsx @@ -85,12 +85,11 @@ const DeleteProjectButton: FC = ({ type = 'danger' }) => { // Submit exit survey to Hubspot for paid projects if (!isFree) { - const feedbackRes = await post(`${API_URL}/feedback/send`, { + const feedbackRes = await post(`${API_URL}/feedback/downgrade`, { projectRef, - subject: 'Subscription cancellation - Exit survey [Delete]', - tags: ['dashboard-exitsurvey'], - category: 'Billing', - message: generateFeedbackMessage(selectedReasons, cancellationMessage), + reasons: selectedReasons.reduce((a, b) => `${a}- ${b}\n`, ''), + additionalFeedback: cancellationMessage, + exitAction: 'delete', }) if (feedbackRes.error) throw feedbackRes.error } From 96e0af2bc1f5e83063d7088bf3605c8b1cc3fd12 Mon Sep 17 00:00:00 2001 From: Long Hoang Date: Tue, 15 Nov 2022 14:07:37 +0800 Subject: [PATCH 02/36] Remove unused import --- .../Settings/General/DeleteProjectPanel/DeleteProjectButton.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/studio/components/interfaces/Settings/General/DeleteProjectPanel/DeleteProjectButton.tsx b/studio/components/interfaces/Settings/General/DeleteProjectPanel/DeleteProjectButton.tsx index 21873e761a1..e450cd1599b 100644 --- a/studio/components/interfaces/Settings/General/DeleteProjectPanel/DeleteProjectButton.tsx +++ b/studio/components/interfaces/Settings/General/DeleteProjectPanel/DeleteProjectButton.tsx @@ -9,7 +9,6 @@ import { API_URL, PRICING_TIER_PRODUCT_IDS } from 'lib/constants' import { delete_, post } from 'lib/common/fetch' import TextConfirmModal from 'components/ui/Modals/TextConfirmModal' import { CANCELLATION_REASONS } from 'components/interfaces/Billing/Billing.constants' -import { generateFeedbackMessage } from 'components/interfaces/Billing/ExitSurvey/ExitSurvey.utils' interface Props { type?: 'danger' | 'default' From 248cd53fc594fcbfe210022e3cc22d6e3ff4c17b Mon Sep 17 00:00:00 2001 From: Isaiah Hamilton Date: Thu, 1 Dec 2022 01:52:55 -0500 Subject: [PATCH 03/36] chore: update architecture image in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c24e86943fa..4c35921e1a5 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ Supabase is a combination of open source tools. We’re building the features of Supabase is a [hosted platform](https://app.supabase.com). You can sign up and start using Supabase without installing anything. You can also [self-host](https://supabase.com/docs/guides/hosting/overview) and [develop locally](https://supabase.com/docs/guides/local-development). -![Architecture](https://user-images.githubusercontent.com/70828596/187547862-ffa9d058-0c3a-4851-a3e7-92ccfca4b596.png) +![Architecture](https://github.com/supabase/supabase/blob/master/apps/docs/public/img/supabase-architecture.png) - [PostgreSQL](https://www.postgresql.org/) is an object-relational database system with over 30 years of active development that has earned it a strong reputation for reliability, feature robustness, and performance. - [Realtime](https://github.com/supabase/realtime) is an Elixir server that allows you to listen to PostgreSQL inserts, updates, and deletes using websockets. Realtime polls Postgres' built-in replication functionality for database changes, converts changes to JSON, then broadcasts the JSON over websockets to authorized clients. From 9c37846130f71295bcc8703ed1a2ecea88a16b7b Mon Sep 17 00:00:00 2001 From: Long Hoang Date: Thu, 1 Dec 2022 18:41:54 +0800 Subject: [PATCH 04/36] Update links to careers page --- apps/www/data/Developers.json | 2 +- apps/www/pages/company.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/www/data/Developers.json b/apps/www/data/Developers.json index da5baac96f6..a29460f0c5b 100644 --- a/apps/www/data/Developers.json +++ b/apps/www/data/Developers.json @@ -20,7 +20,7 @@ { "text": "Careers", "description": "Join the Supabase team and get involved.", - "url": "https://about.supabase.com/careers", + "url": "https://supabase.com/careers", "icon": "M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" } ] diff --git a/apps/www/pages/company.tsx b/apps/www/pages/company.tsx index 04a4b9537d0..bb2775767c8 100644 --- a/apps/www/pages/company.tsx +++ b/apps/www/pages/company.tsx @@ -103,7 +103,7 @@ const Team = () => {

- + From 098135ccdd5e253849a955c2c72cda807aad454c Mon Sep 17 00:00:00 2001 From: Alaister Young Date: Thu, 1 Dec 2022 12:33:29 +0000 Subject: [PATCH 05/36] fix: reset captcha token on sso sign in error --- studio/components/interfaces/SignIn/SignInSSOForm.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/studio/components/interfaces/SignIn/SignInSSOForm.tsx b/studio/components/interfaces/SignIn/SignInSSOForm.tsx index 874e0f6b97d..dbf67ccb353 100644 --- a/studio/components/interfaces/SignIn/SignInSSOForm.tsx +++ b/studio/components/interfaces/SignIn/SignInSSOForm.tsx @@ -44,6 +44,7 @@ const SignInSSOForm = () => { window.location.href = data.url } } else { + setCaptchaToken(null) captchaRef.current?.resetCaptcha() ui.setNotification({ From 17e04bb07281d91850020460cc0115b56adfc90f Mon Sep 17 00:00:00 2001 From: Copple <10214025+kiwicopple@users.noreply.github.com> Date: Thu, 1 Dec 2022 17:12:36 +0100 Subject: [PATCH 06/36] minor edits - tce (#10669) * minor edits * Fix the wierd markup * Update 2022-12-01-transparent-column-encryption-with-postgres.mdx Fix formatting. Co-authored-by: Michel Pelletier --- ...parent-column-encryption-with-postgres.mdx | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/apps/www/_blog/2022-12-01-transparent-column-encryption-with-postgres.mdx b/apps/www/_blog/2022-12-01-transparent-column-encryption-with-postgres.mdx index 75c05cf7f08..260719c186f 100644 --- a/apps/www/_blog/2022-12-01-transparent-column-encryption-with-postgres.mdx +++ b/apps/www/_blog/2022-12-01-transparent-column-encryption-with-postgres.mdx @@ -18,7 +18,7 @@ To understand how TCE works, let's first do a deep-dive into an important encryp
- This post is a sneak peek of a big feature we are shipping on LW6. To not miss a thing, get your ticket for [Supabase Launch Week 6!](https://supabase.com/launch-week). +This post is a sneak peek of a big feature we are shipping on LW6. To not miss a thing, get your ticket for [Supabase Launch Week 6!](https://supabase.com/launch-week).
@@ -28,23 +28,23 @@ The current state-of-the-art in encryption libraries is [libsodium](https://doc. **libsodium** offers a range of APIs for authenticated secret and public key encryption, key derivation, encrypted streaming, [AEAD](https://en.wikipedia.org/wiki/Authenticated_encryption), various forms of hashing, and much more. -This powerful API is available to PostgreSQL using the [**pgsodium**](https://github.com/michelp/pgsodium) extension. **pgsodium** provides all the functionality of the full **libsodium** API, but previously it required developers to set up database encryption themselves, which remained a challenge even for those familiar with database administration. +This powerful API is available to PostgreSQL using the [**pgsodium**](https://github.com/michelp/pgsodium) extension. **pgsodium** provides all the functionality of the full **libsodium** API, but previously it required developers to set up database encryption themselves, which remained a challenge even for those familiar with database administration. -To solve this problem, **pgsodium** now has a full key management API, primarily via the table `pgsodium.key` and the `pgsodium.create_key()` function. This key table contains no raw keys, but instead uses libsodium Key IDs to derive keys that are used internally for encryption. A [key derivation function](https://libsodium.gitbook.io/doc/key_derivation) is used with an internal root key that is unavailable to SQL and not stored in the database, but rather managed by you externally using flexible scripts, or by Supabase automatically as part of our service offering. +To solve this problem, **pgsodium** now has a full key management API, primarily via the table `pgsodium.key` and the `pgsodium.create_key()` function. This key table contains no raw keys, but instead uses libsodium Key IDs to derive keys that are used internally for encryption. A [key derivation function](https://libsodium.gitbook.io/doc/key_derivation) is used with an internal root key that is unavailable to SQL and not stored in the database, but rather managed by you externally using flexible scripts, or by Supabase automatically as part of our service offering. -The simplest way to use **pgsodium** to encrypt and decrypt data is to first create a ******Key ID******. Valid Key IDs are stored in pgsodium in a special extension table, and they can be created using the `pgsodium.create_key()` function. This function takes a number of arguments depending on how it's used, but the simplest case is to create a new key with no arguments: +The simplest way to use **pgsodium** to encrypt and decrypt data is to first create a **Key ID**. Valid Key IDs are stored in pgsodium in a special extension table, and they can be created using the `pgsodium.create_key()` function. This function takes a number of arguments depending on how it's used, but the simplest case is to create a new key with no arguments: ```sql select * from pgsodium.create_key(); -[ RECORD 1 ]---+------------------------------------- id | eaa20d8c-c77c-4985-9f73-2a5f5d1f1e6d -name | +name | status | valid key_type | aead-det key_id | 2 key_context | \x7067736f6469756d created | 2022-11-13 21:19:35.765823+00 -expires | +expires | associated_data | ``` @@ -65,13 +65,13 @@ This produces the following encrypted “ciphertext” using the `aead-det` algo crypto_aead_det_encrypt | \\x099baa820250d7375ed141f8f1936af384bc229f3de1010a6eff6ffdaf3998baffbae75b5cd83d1c469407ff2d3764a428b742 ``` -Now to decrypt the ciphertext, pass it to the decryption function *with the same Key ID*: +Now to decrypt the ciphertext, pass it to the decryption function _with the same Key ID_: ```sql -select * +select * from convert_from(pgsodium.crypto_aead_det_decrypt ( - '\\x099baa820250d7375ed141f8f1936af384bc229f3de1010a6eff6ffdaf3998baffbae75b5cd83d1c469407ff2d3764a428b742', - 'this is associated data', + '\\x099baa820250d7375ed141f8f1936af384bc229f3de1010a6eff6ffdaf3998baffbae75b5cd83d1c469407ff2d3764a428b742', + 'this is associated data', 'eaa20d8c-c77c-4985-9f73-2a5f5d1f1e6d'::uuid ), 'utf8'); ``` @@ -83,24 +83,24 @@ Which recovers the original “plaintext” message: convert_from | this is the message ``` -In the above example, there is *no raw key* like shown in the pgcrypto example above, only a Key ID which is used to derive the key used to encrypt the message and authenticate it with the associated data. In fact, it is impossible for a SQL user to derive the key used above, and if the Key ID is stored, then no decrypted information will leak into backups, disk storage, or the database WAL stream. +In the above example, there is _no raw key_, only a Key ID which is used to derive the key used to encrypt the message and authenticate it with the associated data. In fact, it is impossible for a SQL user to derive the key used above, and if the Key ID is stored, then no encryption keys or decrypted information will leak into backups, disk storage, or the database WAL stream. ## Transparent Column Encryption -As of **pgsodium** 3.0.0 and up, the extension offers a simple and declarative Transparent Column Encryption feature (TCE). This feature is now shipped with all Supabase projects. TCE allows you to specify encrypted columns within a table and generates a new view that “wraps” that table to decrypt the contents. +As of **pgsodium** 3.0.0 and up, the extension offers a simple and declarative Transparent Column Encryption feature (TCE). This feature is now shipped with all Supabase projects. TCE allows you to specify encrypted columns within a table and generates a new view that “wraps” that table to decrypt the contents. -TCE works using two dynamically generated objects for tables that contain encrypted columns: +TCE works using two dynamically generated objects for tables that contain encrypted columns: - an `INSERT UPDATE` trigger that encrypts data when it is inserted or modified - a view that is created to wrap the table to decrypt the data when it is accessed -To “transparently” decrypt the table, access the dynamically generated view *instead of the table*. For every encrypted column in the table, the view will have an additional decrypted column that shows the decrypted result. +To “transparently” decrypt the table, access the dynamically generated view _instead of the table_. For every encrypted column in the table, the view will have an additional decrypted column that shows the decrypted result. -It's worth noting at this point that sometimes there is some confusion about handling encrypted data with TCE. The `T` stands for ***********Transparent*********** which means, you can always see decrypted data through the view, where the decrypted data can't be see is when stored on disk, or in pg_dumps, backups, WAL streams, etc. This is often called ******************Encryption At Rest****************** and is one layer in many that may be used to encrypt and protect your data. +It's worth noting at this point that sometimes there is some confusion about handling encrypted data with TCE. The `T` stands for **Transparent** which means, you can always see decrypted data through the view, where the decrypted data can't be see is when stored on disk, or in pg_dumps, backups, WAL streams, etc. This is often called **Encryption At Rest** and is one layer in many that may be used to encrypt and protect your data. -Often Transparent encryption is understood to be “Transparent Disk Encryption” or “Full Disk Encryption”, this is where a drive is encrypted but reading and writing that drive is decrypted. TCE is similar to this, where data on disk is encrypted, but it is more fine grained, only particular columns are encrypted. The data is also encrypted in the sense that the table stored on disk contains encrypted data, without the view or the key, pg_dumps and backups still contain encrypted data, this is not possible with disk-only encryption. +Often Transparent encryption is understood to be “Transparent Disk Encryption” or “Full Disk Encryption”, this is where a drive is encrypted but reading and writing that drive is decrypted. TCE is similar to this, where data on disk is encrypted, but it is more fine grained, only particular columns are encrypted. The data is also encrypted in the sense that the table stored on disk contains encrypted data, without the view or the key, pg_dumps and backups still contain encrypted data, this is not possible with disk-only encryption. -For the moment TCE only works for columns of type `text` (or types castable to `text` like `json`). Soon we will also support `bytea` and possibly more as use cases and tests get better. +For the moment TCE only works for columns of type `text` (or types castable to `text` like `json`). Soon we will also support `bytea` and possibly more as use cases and tests get better. TCE uses one of PostgreSQL's lesser-known features: [`SECURITY LABEL`](https://www.postgresql.org/docs/current/sql-security-label.html). A security label can be thought of as a simple label which is attached to an object (a table, column, etc). Each label is scoped to an extension and that extension can provide security features depending on the label. @@ -127,7 +127,7 @@ SECURITY LABEL FOR pgsodium IS 'ENCRYPT WITH KEY ID e348034b-3f07-4878-aad6-000511d12826'; ``` -The advantage of this approach is simplicity - the user creates one key and labels a column with it. The cryptographic algorithm for this approach uses a *nonceless* encryption algorithm called `crypto_aead_det_xchacha20()`. This algorithm is written by the author of libsodium and can be found [here](https://github.com/jedisct1/libsodium-xchacha20-siv). +The advantage of this approach is simplicity - the user creates one key and labels a column with it. The cryptographic algorithm for this approach uses a _nonceless_ encryption algorithm called `crypto_aead_det_xchacha20()`. This algorithm is written by the author of libsodium and can be found [here](https://github.com/jedisct1/libsodium-xchacha20-siv). Using one key for an entire column means that whoever can decrypt one row can decrypt them all from a database dump. Also changing (rotating) the key means rewriting the whole table. @@ -153,11 +153,11 @@ Notice also how there is a `DEFAULT` value for the `key_id`. In a way, this give ### One Key ID per Row with Nonce Support -The default cryptographic algorithm for the above approach uses a *nonceless* encryption algorithm called `[crypto_aead_det_xchacha20()](https://github.com/jedisct1/libsodium-xchacha20-siv)`. This algorithm has the advantage that it does not require nonce values, the disadvantage is that duplicate plaintexts will produce duplicate ciphertexts. +The default cryptographic algorithm for the above approach uses a _nonceless_ encryption algorithm called `[crypto_aead_det_xchacha20()](https://github.com/jedisct1/libsodium-xchacha20-siv)`. This algorithm has the advantage that it does not require nonce values, the disadvantage is that duplicate plaintexts will produce duplicate ciphertexts. -Nonces are some extra cryptographic context that is used in many cryptographic algorithms to produce different ciphertexts, even if the plaintexts are the same. The nonce does not have to be secret, but it *does* have to be unique. **pgsodium** comes with a useful function `pgsodium.crypto_aead_det_noncegen()` that will generate a cryptographically secure nonce for you, and in almost all cases it's best to use that function unless you know specifically what you are doing. In password hashing approaches, this is often similar to how a “salt” value is used to deduplicate password hashes. +Nonces are some extra cryptographic context that is used in many cryptographic algorithms to produce different ciphertexts, even if the plaintexts are the same. The nonce does not have to be secret, but it _does_ have to be unique. **pgsodium** comes with a useful function `pgsodium.crypto_aead_det_noncegen()` that will generate a cryptographically secure nonce for you, and in almost all cases it's best to use that function unless you know specifically what you are doing. In password hashing approaches, this is often similar to how a “salt” value is used to deduplicate password hashes. -Duplicate ciphertexts cannot be used to “attack the key”, it can only reveal the duplication. However, duplication is still information. In our examples so far, an attacker might be able to use this information to determine that two accounts share the same credit card number. While not technically breaking the encryption, this still leaks information to an attacker. +Duplicate ciphertexts cannot be used to “attack the key”, it can only reveal the duplication. However, duplication is still information. In our examples so far, an attacker might be able to use this information to determine that two accounts share the same credit card number. While not technically breaking the encryption, this still leaks information to an attacker. ```sql CREATE TABLE credit_cards ( @@ -172,15 +172,15 @@ SECURITY LABEL FOR pgsodium IS 'ENCRYPT WITH KEY COLUMN key_id NONCE nonce'; ``` -This is the most secure form of TCE - there is a unique key ID and a unique nonce per row. +This is the most secure form of TCE - there is a unique key ID and a unique nonce per row. ### One Key ID per Row with Associated Data -The encryption that is used for TCE is one of a family of functions provided by **libsodium** to do Authenticated Encryption with Associated Data or [AEAD Encryption](https://en.wikipedia.org/wiki/Authenticated_encryption). The “associated” data is plaintext (unencrypted) information that is mixed into the authentication signature of the encrypted data, such that when you authenticate the data, you also know that the associated data is authentic. +The encryption that is used for TCE is one of a family of functions provided by **libsodium** to do Authenticated Encryption with Associated Data or [AEAD Encryption](https://en.wikipedia.org/wiki/Authenticated_encryption). The “associated” data is plaintext (unencrypted) information that is mixed into the authentication signature of the encrypted data, such that when you authenticate the data, you also know that the associated data is authentic. -AEAD is helpful because often you have metadata associated with a secret, which isn't confidential but must not be forged. +AEAD is helpful because often you have metadata associated with a secret, which isn't confidential but must not be forged. -In our credit card example, we might associate a "`credit_card_number`" with an "`account_id`". But what if a malicious actor wanted to use someone else's credit card on their own account? If someone could forge the `account_id` data column, swapping an `account_id` with their own `account_id`, then you could be tricked into using the wrong credit card. By “associating” the `account_id` with the `credit_card_number`, it cannot be forged without throwing an error. +In our credit card example, we might associate a "`credit_card_number`" with an "`account_id`". But what if a malicious actor wanted to use someone else's credit card on their own account? If someone could forge the `account_id` data column, swapping an `account_id` with their own `account_id`, then you could be tricked into using the wrong credit card. By “associating” the `account_id` with the `credit_card_number`, it cannot be forged without throwing an error. Like above, this is done simply by extending the security label with the associated data column: @@ -202,18 +202,18 @@ The new label indicates which column is to be associated with the secret, and th ## Using an Encrypted Table -Now that you have TCE setup for a table, it's easy to use by simply inserting data into the table, and querying that data by looking at its generated view. The view is named `decrypted_` and by default is in the same schema as your table: +Now that you have TCE setup for a table, it's easy to use by simply inserting data into the table, and querying that data by looking at its generated view. The view is named `decrypted_` and by default is in the same schema as your table: ```sql INSERT INTO credit_cards ( credit_card_number, account_id -) +) VALUES ('1234-5678-8765-4321', 123); ``` -Now that you have inserted data, look at the table and notice how the credit card number is encrypted. This is the data that is stored on disk, the encrypted card number, the key id, and the account id, ********************************but the key itself is not stored********************************. This means if someone gets a backup or dump of your database, they cannot decrypt the credit card number, they do not have the key, only the key ID: +Now that you have inserted data, look at the table and notice how the credit card number is encrypted. This is the data that is stored on disk, the encrypted card number, the key id, and the account id, **but the key itself is not stored**. This means if someone gets a backup or dump of your database, they cannot decrypt the credit card number, they do not have the key, only the key ID: ```sql > select * from credit_cards where account_id = 123; @@ -238,11 +238,11 @@ key_id | 7f753c4f-8c68-457a-8801-1798b2e9f44d nonce | \x300a14aa721184ff7cf0f6bf088da267 ``` -Notice how there is a new column called `decrypted_credit_card_number`. This column is not stored in database or on disk at all, it is generated “on-the-fly” as you select from the view. Database dumps do not contain this information, only the view itself, and most importantly, *************************************raw decryption keys are never stored*************************************. +Notice how there is a new column called `decrypted_credit_card_number`. This column is not stored in database or on disk at all, it is generated “on-the-fly” as you select from the view. Database dumps do not contain this information, only the view itself, and most importantly, **raw decryption keys are never stored**. ## Future possibilities -We're always thinking about the future possibilities for features and tools that we can bring to the PostgreSQL community, and we'd love to hear from you about what kind of encryption features you'd like to see. Some things we've considered but not yet explored yet are: +We're always thinking about the future possibilities for features and tools that we can bring to the PostgreSQL community, and we'd love to hear from you about what kind of encryption features you'd like to see. Some things we've considered but not yet explored yet are: - Built-in Key Management Server (KMS) with REST API ala AWS or GCP. - Seamless Integration with external KMS services for key management. @@ -251,7 +251,7 @@ We're always thinking about the future possibilities for features and tools that - Group encryption using [signcryption](https://github.com/jedisct1/libsodium-signcryption) - Your idea here? -There's a lot of potential in the world of cryptography with Postgres and pgsodium, and we'd love to hear any ideas you may have as well. Join us in our [Discord #encryption channel](https://discord.com/channels/839993398554656828/1009906326480101417) if you want to chat more about it with us! +There's a lot of potential in the world of cryptography with Postgres and pgsodium, and we'd love to hear any ideas you may have as well. Join us in our [Discord #encryption channel](https://discord.com/channels/839993398554656828/1009906326480101417) if you want to chat more about it with us! ## More Postgres Resources From dbcafd687e29f97c12f22439d9b6dca6a21d2029 Mon Sep 17 00:00:00 2001 From: dng Date: Thu, 1 Dec 2022 11:31:59 -0800 Subject: [PATCH 07/36] Postgres CDC -> Postgres Changes (#10649) * Postgres CDC -> Postgres Changes * Fix typo * docs: update Realtime description from CDC to Changes Co-authored-by: Wen Bo Xie --- .../docs/components/Navigation/Navigation.constants.ts | 2 +- apps/docs/pages/features.mdx | 4 ++-- apps/docs/pages/guides/realtime.mdx | 10 +++++----- .../{postgres-cdc.mdx => postgres-changes.mdx} | 10 +++++----- apps/docs/pages/guides/realtime/quickstart.mdx | 4 ++-- apps/docs/pages/index.mdx | 2 +- apps/docs/public/sitemap.xml | 2 +- apps/www/data/Pricing.json | 2 +- apps/www/lib/redirects.js | 4 ++-- apps/www/pages/realtime/Realtime.tsx | 2 +- 10 files changed, 21 insertions(+), 21 deletions(-) rename apps/docs/pages/guides/realtime/{postgres-cdc.mdx => postgres-changes.mdx} (83%) diff --git a/apps/docs/components/Navigation/Navigation.constants.ts b/apps/docs/components/Navigation/Navigation.constants.ts index 5bfb8aa40df..3c407085da2 100644 --- a/apps/docs/components/Navigation/Navigation.constants.ts +++ b/apps/docs/components/Navigation/Navigation.constants.ts @@ -237,7 +237,7 @@ export const menuItems: NavMenu = { items: [ { name: 'Overview', url: '/guides/realtime', items: [] }, { name: 'Quickstart', url: '/guides/realtime/quickstart', items: [] }, - { name: 'Postgres CDC', url: '/guides/realtime/postgres-cdc', items: [] }, + { name: 'Postgres Changes', url: '/guides/realtime/postgres-changes', items: [] }, { name: 'Rate Limits', url: '/guides/realtime/rate-limits', items: [] }, ], }, diff --git a/apps/docs/pages/features.mdx b/apps/docs/pages/features.mdx index 06152162e48..22a1dfd567a 100755 --- a/apps/docs/pages/features.mdx +++ b/apps/docs/pages/features.mdx @@ -92,7 +92,7 @@ Fast GraphQL APIs using our custom Postgres GraphQL extension. [Docs](/docs/guid ### Realtime Database changes -Receive your database changes through websockets. [Docs](/docs/guides/realtime/postgres-cdc). +Receive your database changes through websockets. [Docs](/docs/guides/realtime/postgres-changes). ### User Broadcasting @@ -156,7 +156,7 @@ Both Postgres and the Supabase Platform are production-ready. Some tools we offe | Database | Point-in-Time Recovery | `alpha` | | Database | Vault | `alpha` | | Studio | | `GA` | -| Realtime | Postgres CDC | `GA` | +| Realtime | Postgres Changes | `GA` | | Realtime | Broadcast | `beta` | | Realtime | Presence | `beta` | | Storage | Backend (S3) | `GA` | diff --git a/apps/docs/pages/guides/realtime.mdx b/apps/docs/pages/guides/realtime.mdx index acf13a0f57b..e6b8ce7e283 100644 --- a/apps/docs/pages/guides/realtime.mdx +++ b/apps/docs/pages/guides/realtime.mdx @@ -3,7 +3,7 @@ import Layout from '~/layouts/DefaultGuideLayout' export const meta = { id: 'realtime', title: 'Realtime', - description: 'Supabase Realtime with Broadcast, Presence, and Postgres CDC.', + description: 'Supabase Realtime with Broadcast, Presence, and Postgres Changes.', sidebar_label: 'Overview', } @@ -11,11 +11,11 @@ Supabase provides a globally distributed cluster of [Realtime](https://github.co - [Broadcast](#broadcast): Send ephemeral messages from client to clients with low latency. - [Presence](#presence): Track and synchronize shared state between clients. -- [Postgres CDC](#postgres-cdc): Listen to Postgres database changes and send them to authorized clients. +- [Postgres Changes](#postgres-changes): Listen to Postgres database changes and send them to authorized clients. A [channel](https://hexdocs.pm/phoenix/channels.html) is the basic building block of Realtime and narrows the scope of data flow to subscribed clients. You can think of a channel as a chatroom where participants are able to see who's online and send and receive messages; similar to a Discord or Slack channel. -All clients can connect to a channel and take advantage of the built-in features, Broadcast and Presence, while extenstions, like Postgres CDC, must be enabled prior to use. +All clients can connect to a channel and take advantage of the built-in features, Broadcast and Presence, while extenstions, like Postgres Changes, must be enabled prior to use. ## Broadcast @@ -37,9 +37,9 @@ Clients are free to come-and-go as they please, and as long as they are all subs The neat thing about Presence is that if a client is suddenly disconnected (for example, they go offline), their state will be automatically removed from the shared state. If you've ever tried to build an “I'm online” feature which handles unexpected disconnects, you'll appreciate how useful this is. -## Postgres CDC +## Postgres Changes -Postgres Change Data Capture (CDC) enables you to listen to database changes and have them broadcast to authorized clients based on [Row Level Security (RLS)](/docs/guides/auth/row-level-security) policies. +Postgres Changes enable you to listen to database changes and have them broadcast to authorized clients based on [Row Level Security (RLS)](/docs/guides/auth/row-level-security) policies. This works by Realtime polling your database's logical replication slot for changes, passing those changes to the [apply_rls](https://github.com/supabase/walrus#reading-wal) SQL function to determine which clients have permission, and then using Broadcast to send those changes to clients. diff --git a/apps/docs/pages/guides/realtime/postgres-cdc.mdx b/apps/docs/pages/guides/realtime/postgres-changes.mdx similarity index 83% rename from apps/docs/pages/guides/realtime/postgres-cdc.mdx rename to apps/docs/pages/guides/realtime/postgres-changes.mdx index c8d20133f3a..79a76e884b2 100644 --- a/apps/docs/pages/guides/realtime/postgres-cdc.mdx +++ b/apps/docs/pages/guides/realtime/postgres-changes.mdx @@ -1,18 +1,18 @@ import Layout from '~/layouts/DefaultGuideLayout' export const meta = { - id: 'postgres-cdc', - title: 'Postgres CDC', - description: "Getting started with Realtime's Postgres CDC feature", + id: 'postgres-changes', + title: 'Postgres Changes', + description: "Getting started with Realtime's Postgres Changes feature", } -Realtime's Postgres Change Data Capture (CDC) feature listens for database changes and sends them to clients. Clients are required to subscribe with a JWT dictating which changes they are allowed to receive based on the database's [Row Level Security](/docs/guides/auth/row-level-security). +Realtime's Postgres Changes feature listens for database changes and sends them to clients. Clients are required to subscribe with a JWT dictating which changes they are allowed to receive based on the database's [Row Level Security](/docs/guides/auth/row-level-security). Anyone with access to a valid JWT signed with the project's JWT secret is able to listen to your database's changes, unless tables have [Row Level Security](/docs/guides/auth/row-level-security) enabled and policies in place. Clients can choose to receive `INSERT`, `UPDATE`, `DELETE`, or `*` (all) changes for all changes in a schema, a table in a schema, or a column's value in a table. Your clients should only listen to tables in the `public` schema and you must first enable the tables you want your clients to listen to. -Postgres CDC works out of the box for tables in the `public` schema. You can listen to tables in your private schemas by granting table `SELECT` permissions to the database role found in your access token. You can run a query similar to the following: +Postgres Changes works out of the box for tables in the `public` schema. You can listen to tables in your private schemas by granting table `SELECT` permissions to the database role found in your access token. You can run a query similar to the following: ```sql GRANT SELECT ON "private_schema"."table" TO authenticated; diff --git a/apps/docs/pages/guides/realtime/quickstart.mdx b/apps/docs/pages/guides/realtime/quickstart.mdx index 02bc5b9177b..5d384d5f874 100644 --- a/apps/docs/pages/guides/realtime/quickstart.mdx +++ b/apps/docs/pages/guides/realtime/quickstart.mdx @@ -7,7 +7,7 @@ export const meta = { sidebar_label: 'Quickstart', } -Learn how to build [multiplayer.dev](https://multiplayer.dev), a collaborative app that demonstrates Broadcast, Presence, and Postgres CDC using [Realtime](/docs/guides/realtime). +Learn how to build [multiplayer.dev](https://multiplayer.dev), a collaborative app that demonstrates Broadcast, Presence, and Postgres Changes using [Realtime](/docs/guides/realtime).