Skip to content

Commit db2848a

Browse files
authored
Merge pull request #593 from opengisch:QF-6348-documentation_on_user_level_secrets_for_each_individual_collaborator
Add user level secrets for each individual collaborator on Nyuki
2 parents 1e09ff8 + 3d8f00b commit db2848a

File tree

4 files changed

+212
-26
lines changed

4 files changed

+212
-26
lines changed
95.4 KB
Loading
177 KB
Loading
184 KB
Loading

documentation/reference/qfieldcloud/secrets.en.md

Lines changed: 212 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,51 +5,71 @@ tx_slug: documentation_reference_qfieldcloud_secrets
55

66
# Secrets
77

8-
Secrets are Project settings that are securely stored in an encrypted way.
9-
Jobs will automatically have access to project's secrets.
8+
Secrets are project settings that are securely stored in an encrypted way.
9+
Jobs will automatically have access to the project's secrets, allowing for secure connections to external services without exposing credentials in your project files.
1010

11-
There are two types of secrets in QFieldCloud:
11+
## Types of Secrets
1212

13-
- **environment variables** - Environment variables will be available to QGIS while your project jobs are running.
14-
- **pg_service configurations** - Adding a PostgreSQL/PostGIS connection as defined in the `pg_service.conf` configuration file.
13+
There are two types of secrets you can create in QFieldCloud:
1514

15+
- **Environment variables:** These will be available to QGIS as environment variables while your project jobs are running.
16+
You need to provide a name (capitals only) and a value.
17+
18+
- **pg_service configurations:** This allows you to add a PostgreSQL/PostGIS connection as defined [in a `pg_service.conf` configuration file](https://www.postgresql.org/docs/current/libpq-pgservice.html).
19+
20+
!![Project secret page after pressing the **Add a new secret** button.](../../assets/images/secrets.png)
1621

1722
!!! warning
18-
QFieldCloud makes sure your credentials are stored in a secured and encrypted manner. Nevertheless, we advice our users to use roles with the least privileges in shared environments to prevent potential leakage.
19-
Also note all users with upload file permissions can potentially access the values of those credentials too.
23+
QFieldCloud makes sure your credentials are stored in a secured and encrypted manner.
24+
**We strongly advice to allocate users the least privileges in shared environments to prevent potential leakage.**
25+
Users who have the permission to upload files may also have access to the corresponding credentials.
2026

27+
## Environment variable
2128

22-
## Adding a new secret
29+
Environment variables will be available to QGIS while your project jobs are running.
2330

24-
Adding a new secret on QFieldCloud is an easy process of only three steps.
31+
You need to fill in the environment variable name (capitals only) and the environment variable value as free text.
2532

26-
1. Navigating to the project' secrets page.
27-
2. Pressing **Add a new secret** button and choosing the type of secret you want to add.
28-
3. Storing the secret contents.
33+
!![Adding an environment variable.](../../assets/images/secrets-envvar.png)
2934

30-
!![Project secret page after pressing the **Add a new secret** button.](../../assets/images/secrets.png)
35+
## Secrets and Precedence
3136

32-
!!! note
33-
Once added, a secret can only be removed, but cannot be edited.
37+
To provide granular control over data access, secrets in QFieldCloud can be defined at three different hierarchical levels.
38+
When a new job is initiated, QFieldCloud will access the secrets available and follow the following hierarchical order of precedence:
3439

40+
1. **User-Assigned Secret (Highest Precedence):** A secret defined within a project and assigned to a specific user. This is the most specific level and overrides all others for that user.
3541

36-
## Environment variable
42+
2. **Project-Level Secret:** A general secret defined for a specific project. It applies to all project members unless a user-assigned secret is present.
3743

38-
Environment variables will be available to QGIS while your project jobs are running.
44+
3. **Organization-Level Secret (Lowest Precedence):** A secret defined at the organization level. It is used as a fallback for all projects within the organization that require it, provided no project or user-level secret has been set.
3945

40-
You need to fill in the environment variable name (capitals only) and the environment variable value as free text.
46+
This hierarchical system allows an administrator to set a general, low-privilege database role at the organization level, while assigning more privileged roles for specific projects or trusted individual users.
4147

42-
!![Adding an environment variable.](../../assets/images/secrets-envvar.png)
48+
### Secret Configuration
4349

50+
In order to add a new secret, you first need to decide what kind of secret is needed for your project.
4451

45-
## pg_service configuration
52+
#### Organization Level Secret
4653

47-
Adding a PostgreSQL/PostGIS connection as defined in `pg_service.conf` configuration file. The "Advanced editor" allows to paste the `pg_service.conf` file contents directly. If you use multiple service definitions, you should add multiple secrets for each of them.
54+
Navigate to your organization's settings and select the **Secrets** tab.
55+
Secrets added here will be available to all projects within the organization unless overridden.
4856

49-
!!! note
50-
QFieldCloud secrets are available only during project's job runs, which allows you to configure your PostgreSQL layers as "Offline editing". You **cannot** use QFieldCloud secrets to distribute `pg_service.conf` files across devices. For security reasons, you have to do this manually. You can read [how to configuring QField to use a `pg_service.conf`](../../how-to/pg-service.md) file.
57+
#### Project Level Secret
58+
59+
Navigate to your project's settings and select the **Secrets** tab. Secrets added here will override any organization-level secrets with the same name.
60+
61+
#### User-Assigned Level
62+
63+
Within a project's **Secrets** tab, you can add a new secret and explicitly assign it to a specific project member.
64+
This provides the highest level of precedence.
65+
66+
#### Adding a secret
5167

52-
To add a PostgreSQL service you can use either the simple visual editor, or directly edit the service configuration as plain text.
68+
To add a new secret to give access to your Postgres/PostGIS database, follow the same format as defined in the `pg_service.conf` configuration file.
69+
This can either be done manually as plain text or through the "Advanced editor".
70+
The "Advanced editor" allows you to paste the `pg_service.conf` file contents directly.
71+
72+
You can add the following information:
5373

5474
- service name
5575
- database name
@@ -59,10 +79,176 @@ To add a PostgreSQL service you can use either the simple visual editor, or dire
5979
- database port
6080
- database SSL connection
6181

62-
For other service settings you can use the **Add extra pgservice field** button to add pairs of settings and their values. Alternatively, you can edit the service configuration directly as plain text.
82+
For other service settings you can use the **Add extra pgservice field** button to add additional settings and their values.
83+
84+
If you use multiple service definitions, you should add multiple secrets for each of them.
85+
86+
!!! note
87+
Once added, a secret can only be removed, but cannot be edited.
88+
89+
!!! note
90+
QFieldCloud secrets are available only during project's job runs, which allows you to configure your PostgreSQL layers as "Offline editing". You **cannot** use QFieldCloud secrets to distribute `pg_service.conf` files across devices. For security reasons, you have to do this manually. You can read [how to configuring QField to use a `pg_service.conf`](../../how-to/pg-service.md) file.
6391

6492
!![Adding a PostgreSQL service - Simple editor.](../../assets/images/secrets-pgservice-simple.png)
6593

66-
The advanced configuration allows you to directly edit the settings as plain text. This is convenient in cases you want to copy and paste your settings directly from a `pg_service.conf` file.
94+
The "Advanced editor" allows you to directly edit the settings as plain text.
95+
This is convenient in cases you want to copy and paste your settings directly from your `pg_service.conf` file.
6796

6897
!![Adding a PostgreSQL service - Advanced editor.](../../assets/images/secrets-pgservice-advanced.png)
98+
99+
### Example
100+
101+
The following example will go through the addition and verification process of the above explained hierarchy.
102+
You can add additional attributes to your table to check and confirm that only users with the according roles have the ability to add new features.
103+
104+
### Part 1: PostgreSQL Database Configuration
105+
106+
First, the database needs to be configured and the user roles defined.
107+
Following an automated trigger needs to be added, to populate the allocated user column inside the database.
108+
109+
#### 1. Database and Extension Instantiation
110+
111+
Start with creating a new database and enable the necessary `postgis` and `uuid-ossp` extensions.
112+
113+
```sql
114+
-- Create a new database with a specified name, owner, and encoding.
115+
CREATE DATABASE db-og-secrets OWNER qfield ENCODING 'UTF8';
116+
117+
-- Connect to the newly created database.
118+
\c db-og-secrets
119+
120+
-- Install the required extensions if they do not already exist.
121+
CREATE EXTENSION IF NOT EXISTS postgis;
122+
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
123+
```
124+
125+
#### 2. Establishment of Roles
126+
127+
Create three distinct user roles to simulate the tiered permission structure that QFieldCloud secrets will manage.
128+
129+
```sql
130+
-- Create three roles, each with login privileges and an assigned password.
131+
CREATE ROLE ninja_org LOGIN PASSWORD 'your_strong_password_for_org';
132+
CREATE ROLE ninja_project LOGIN PASSWORD 'your_strong_password_for_project';
133+
CREATE ROLE ninja_user LOGIN PASSWORD 'strong_password_for_user_001';
134+
```
135+
136+
#### 3. Schema and Table Definition
137+
138+
Create a schema and a table for point geometries.
139+
The table will include a `pg_user` field to automatically record which role was responsible for the data insertion.
140+
141+
```sql
142+
-- Create a schema named 'ninja' if it does not already exist.
143+
CREATE SCHEMA IF NOT EXISTS ninja;
144+
145+
-- Create a table within the 'ninja' schema with the specified columns.
146+
CREATE TABLE IF NOT EXISTS ninja.ninja_point (
147+
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
148+
pg_user TEXT,
149+
some_value TEXT NOT NULL,
150+
geom GEOMETRY(POINT, 4326)
151+
);
152+
```
153+
154+
#### 4. Implementation of an Automated User-Attribution Trigger
155+
156+
This trigger automatically populates the `pg_user` field with the identifier of the `current_user` whenever a record is inserted or updated.
157+
158+
```sql
159+
-- Define a trigger function to update the pg_user field.
160+
BEGIN;
161+
SET LOCAL SEARCH_PATH TO ninja, public;
162+
163+
CREATE OR REPLACE FUNCTION update_pg_user() RETURNS TRIGGER AS $$
164+
BEGIN
165+
NEW.pg_user := current_user;
166+
RETURN NEW;
167+
END;
168+
$$ LANGUAGE plpgsql SET search_path FROM CURRENT;
169+
170+
COMMIT;
171+
```
172+
173+
And assign the trigger to the ninja_point table for INSERT or UPDATE events.
174+
175+
```sql
176+
BEGIN;
177+
SET LOCAL SEARCH_PATH TO ninja, public;
178+
179+
DROP TRIGGER IF EXISTS trg_ninja_point_update_pg_user ON ninja.ninja_point;
180+
181+
CREATE TRIGGER trg_ninja_point_update_pg_user
182+
BEFORE INSERT OR UPDATE ON ninja_point
183+
FOR EACH ROW EXECUTE FUNCTION update_pg_user();
184+
185+
COMMIT;
186+
```
187+
188+
#### 5. Permission Granting
189+
190+
To ensure security and proper data access, grant each role only the permissions required for its function.
191+
This approach follows the principle of least privilege.
192+
193+
First, all roles need USAGE permission on the ninja schema to access any tables within it.
194+
195+
```sql
196+
GRANT USAGE ON SCHEMA ninja TO ninja_org, ninja_project, ninja_user;
197+
```
198+
199+
##### Role-Based Access
200+
201+
- **`ninja_user` (Read-Only)**: This role is for general users who only need to view data.
202+
203+
- Grants: `SELECT`
204+
205+
- **`ninja_project` (Read/Write)**: This role is for project members who need to view, add, and modify data.
206+
207+
- Grants: `SELECT`, `INSERT`, `UPDATE`
208+
209+
- **`ninja_org` (Admin)**: This role is for organization owners who require full control over the data, including deleting records and managing foreign key relationships.
210+
211+
- Grants: `SELECT`, `INSERT`, `UPDATE`, `DELETE`, `REFERENCES`
212+
213+
```sql
214+
-- Grant table permissions based on role responsibilities
215+
216+
-- Read-only access for general users
217+
GRANT SELECT ON TABLE ninja.ninja_point TO ninja_user;
218+
219+
-- Read and write access for project members
220+
GRANT SELECT, INSERT, UPDATE ON TABLE ninja.ninja_point TO ninja_project;
221+
222+
-- Full administrative access for organization owners
223+
GRANT ALL PRIVILEGES ON TABLE ninja.ninja_point TO ninja_org;
224+
```
225+
226+
### Part 2: QFieldCloud and QGIS Project Configuration
227+
228+
Direct to QFieldCloud to set the secrets at different levels in QFieldCloud.
229+
230+
#### Scenario 1: Organization-Level Secret Application
231+
232+
1. **Secret Addition:** Navigate to the settings page of your organization and select the **Secrets** from there.
233+
Add a new `pg_service` secret using the credentials for the **`ninja_org`** role.
234+
235+
2. **Verification:** To ensure that the secret is set at the right level, you can now create a new feature in the `ninja_point` layer inside QField.
236+
Once synchronized with QFieldCloud, the `pg_user` attribute for the new feature is expected to be **`ninja_org`**.
237+
238+
#### Scenario 2: Project-Level Secret Application (Precedence over Organization)
239+
240+
1. **Secret Addition:** Navigate to the settings page of your project and select the **Secrets** from there.
241+
Add a new `pg_service` secret with the same service name as previous, but this time use the credentials for the **`ninja_project`** role.
242+
243+
2. **Verification:** To ensure that the secret is set at the right level, you can create a new feature in the `ninja_point` layer inside QField.
244+
Once synchronized with QFieldCloud, the `pg_user` attribute for the new feature is expected to be **`ninja_project`**
245+
This demonstrates that the project-level secret correctly superseeds the organization-level secret.
246+
247+
#### Scenario 3: User-Level Secret Application (Highest Precedence)
248+
249+
1. **Secret Creation:** Navigate to the settings page of your project and select the **Secrets** tab.
250+
Add a new `pg_service` secret.
251+
Use the credentials for the **`ninja_user`** role and explicitly assign this secret to your user account.
252+
253+
2. **Verification:** Create a new feature in QField.
254+
The `pg_user` attribute for this feature is expected to be **`ninja_user`**, confirming that the user-assigned secret holds the highest level of precedence in the hierarchy.

0 commit comments

Comments
 (0)