docs/security-and-privacy/processing-of-personal-data/README.md
Status of this document: 2024-09-22
This document outlines how personal data flows through the OpenProject software and aims to assist data controllers in organizations using OpenProject on their own infrastructure in creating GDPR-compliant data protection documentation.
Note: Customers of the OpenProject GmbH that subscribed to the OpenProject Enterprise Edition Cloud (a software-as-a-service) please check the following legal documents:
OpenProject is a project management and team collaboration software. The personal data processed by the software can be categorized into four different groups:
Depending on the individual permission and authentication settings an OpenProject project can be accessed for read-only anonymously without a user account. The OpenProject community platform is an example of an OpenProject installation where individual projects where set to public.
Anonymity is not complete because the underlying webserver might still generate its common logfile (weblog).
To sign-in to the OpenProject platform, the registration of a user account is required. For registered user's the following personal data are processed:
Note: Administrators can add so-called custom fields to their OpenProject installation which extend the data fields of a user.
Depending on the individual use and permissions of the user the following personal data is processed:
Assignment of a person to a project (author, project member)
Change history
Person mentioned in a project overview
Person mentioned in a project attribute
Persons mentioned in a project status information
Activities in OpenProject are automatically journalized. It allows users to understand the change history of those objects (e.g. the baseline comparison).
Independently of the change history every interaction (i.e. web request) of a browser or other client results in an entry written to the server logfiles. These files support the operation of the application as they provide information on faulty behavior of the system (i.e. bugs and lack of performance).
Those log files contain the following person related data:
Note: Passwords are not logged in plain text.
The data listed above is generated upon entering the application. When actually processing the request within the application, events deemed noteworthy by the developers might be logged additionally. An example of this are failed login attempts.
Logfiles are automatically removed based on a first-in-first-out mechanism. This is done to limit the disk space which ensures the server's operation and at the same time serves as a means to erase the log entries once they have served their purpose of supporting operations. By default the retention period is determined by the size of the logfile. Once the logfile reaches its storage limit, the oldest entries are removed.
As such, the log entries are not kept for a fixed period of time. If there are a lot of requests, old entries are removed faster then if there are less requests. Administrators of an OpenProject installation might decide to configure a different behavior that factors in the age of the log entries.
Detailed technical information about the logging mechanism can be found in the operations documentation:
Note: Additional logfiles might be generated by systems that are part of the used network infrastructure (e.g., load balancers, proxying servers, or other network components). These are out of scope for this documentation but they often contain additional information such as the IP address. On the other hand, since TLS is employed for all connections by default, those intermediary systems do not have access to the full request body so they are not able to see for example the request parameters.
The following diagram provides an overview of the flows of personal data in OpenProject. This applies to the different installation methods.
%%{init: {'theme':'neutral'}}%%
flowchart TD
browser[Web browser] -->|"HTTP(s) requests"| loadbalancer(Load balancer / proxy)
A1[Native client] -->|"HTTP(s) requests"| loadbalancer
A2[SVN or Git client] -->|"HTTP(s) requests"| loadbalancer
loadbalancer -->|Proxy| openproject
subgraph openproject[OpenProject Core Application]
openprojectrailsapp[Rails application]
C[Puma app server]
D[Background worker]
end
subgraph integrations[External Integrations]
direction TB
idp["Identity provider (idp)"]
nex["Nextcloud (nex)"]
osh["OneDrive (osh)"]
gih["GitHub (gih)"]
gil["GitLab (gil)"]
cal["Calendar (cal)"]
O["API integrations (api)"]
end
subgraph services[Internal Services]
direction TB
M[Memcached]
P[PostgreSQL]
S[Object storage or NFS]
email["Email gateways (eml)"]
end
openproject <--> services
openproject --> integrations
loadbalancer <--> integrations
subgraph localclients[Local Client / User device]
direction TB
browser
A1
A2
end
As a web application, the primary data flow is between the user's web browser (or attached API clients) through an external proxying web server (this might be a load balancer or proxying server). Depending on the individual setup the proxying server is responsible for terminating TLS connections for the course of this document - although encrypted connections between Load balancer and Puma server are possible. In case of packaged or Kubernetes installations, this proxying server might be part of the OpenProject stack (e.g., an Apache2 packaged installation server or nginx ingress).
The external web server acts as a proxy/reverse-proxy for the OpenProject Puma app server, relaying requests for it to handle and respond. In the course of the request, access to external services such as the PostgreSQL database, a caching server, or attached storages might be performed. In case of S3-compatible object storage set ups, OpenProject performs calls to the object storage to put or request files from it. Likewise, for network-attached storages linked into the application, underlying network requests are performed. These are out of scope for this evaluation, as they are provided and maintained by the operator of the system.
In the course of using the application, background tasks are enqueued in the database such as outgoing emails, cleanup tasks, or notification processing. These tasks are performed in a separate process, the background worker queue. This process accesses the same services as the application server process to access or modify data. It might connect to external integrations such as a Nextcloud or OneDrive instance to set up file sharings depending on actions performed by the users.
Exemplary request flow
User request: An end-user sends an HTTPS request to the load balancer or proxying server.
Load balancer: The external load balancer or proxying server receives the request, terminates TLS, and forwards the HTTP request to the Puma application server.
Puma app server: Processes the request and invokes the appropriate Rails middlewares and controller.
Rails application:
Authenticates the user according to the mechanisms outlined in the secure coding guidelines
Retrieves or updates resources to the PostgreSQL database via models
Renders the appropriate views
Response: Sends the HTTP response back through the Puma server and load balancer to the end-user.
Background worker: Operates on periodical background data, or performs actions requested by the web request of user (sending emails, exporting data, communicating with external services)
%%{init: {'theme':'neutral'}}%%
flowchart LR
Browser <-->|idp-01| IDP
IDP <-->|idp-02| openproject[OpenProject]
Browser <-->|idp-03| openproject
subgraph IDP[Identity Provider]
direction LR
ssoprovider[SSO provider]
LDAP
end
subgraph openproject["Relying Party (OpenProject) "]
direction LR
ssoclient[SSO client]
ldapauthentication[LDAP authentication]
ldapgroupsync[LDAP group sync]
end
subgraph localclients[Local clients]
direction LR
Browser
end
bu-01bu-02bu-03bu-05 (group memberships trough LDAP groups)idp-01 TLSidp-02 TLSidp-03 TLS%%{init: {'theme':'neutral'}}%%
flowchart LR
A[User's email client] <-->|eml-01| B[User's email hoster]
B <-->|eml-02| C[Email gateway]
C <-->|eml-03| D[Email notification service]
subgraph localclients[Local clients]
direction TB
A
end
subgraph internal[Internal services]
direction TB
C
end
subgraph external[External services]
direction TB
A
B
end
subgraph OpenProject
direction TB
D
end
bu-01bu-04bu-05cc-01cm-01cp-01cw-02eml-01 TLS (not controlled by the OpenProject system)
eml-02 TLS (not controlled by the OpenProject system)
eml-03 TLS (encryption can be activated in the email settings in the OpenProject Administration)
Note: OpenProject does not support end-to-end encryption using GPG or S/MIME.
%%{init: {'theme':'neutral'}}%%
flowchart LR
opicalapi[OpenProject's iCal API] --> |cal-01|B
B[Calendar web application] -->|cal-03| localcalendarapp[Local calendar application]
opicalapi -->|cal-02| localcalendarapp
subgraph localclient[Local clients]
direction TB
localcalendarapp
end
subgraph external[External services]
direction TB
B
end
subgraph OpenProject
direction TB
projectcalendar[Project calendar] --> opicalapi
end
bu-01bu-03 (iCalendar access tokens)cm-01cp-02ct-01cal-01 TLScal-02 TLS (not controlled by the OpenProject system)cal-03 TLS (not controlled by the OpenProject system)%%{init: {'theme':'neutral'}}%%
flowchart LR
Browser <--> |nex-01| openproject
Browser <-->|nex-02| nextcloud
nextclouddesktopclient[Nextcloud desktop client] <-->|nex-03| nextcloudapi
appopenprojectintegration <-->|nex-04| openprojectapi
subgraph local[Local clients]
Browser
nextclouddesktopclient
end
subgraph openproject[OpenProject]
opnextcloudintegrattion[Nextcloud integration]
openprojectapi[API]
end
subgraph nextcloud[Nextcloud]
groupfolder[Team folders app]
appopenprojectintegration[OpenProject integration app]
nextcloudapi[API]
end
bu-01bu-03cf-01nex-01 TLSnex-02 TLSnex-03 TLSnex-04 TLS%%{init: {'theme':'neutral'}}%%
flowchart LR
Browser <--> |osh-01| openproject
Browser <-->|osh-02| onedrive
onedrivedesktopclient[Nextcloud desktop client] <-->|osh-03| onedriveapi
appopenprojectintegration <-->|osh-04| openprojectapi
subgraph local[Local clients]
Browser
onedrivedesktopclient[OneDrive desktop client]
end
subgraph openproject[OpenProject]
oponedrivetegration[OneDrive integration]
openprojectapi[API]
end
subgraph onedrive[OneDrive]
appopenprojectintegration[OpenProject integration app]
onedriveapi[API]
end
bu-01bu-03cf-01osh-01 TLSosh-02 TLSosh-03 TLSosh-04 TLS%%{init: {'theme':'neutral'}}%%
flowchart LR
gitclient <-->|gih-01| githubapi
githubapi <-->|gih-02| opgithubintegration
githubwebhooks -->|gih-03| opgithubintegration
subgraph GitHub
direction TB
githubapi[API]
githubwebhooks[Webhooks]
end
subgraph localclients[Local clients]
direction TB
gitclient[Git client]
end
subgraph openproject[OpenProject]
direction TB
opgithubintegration[Github integration] --- workpackagesmodule[Work packages module]
end
gih-01 TLSgih-02 TLSgih-03 TLS%%{init: {'theme':'neutral'}}%%
flowchart LR
gitclient <-->|gil-01| gitlabapi
gitlabapi <-->|gil-02| opgitlabintegration
gitlabwebhooks -->|gil-03| opgitlabintegration
subgraph GitLab
direction TB
gitlabapi[API]
gitlabwebhooks[Webhooks]
end
subgraph localclients[Local clients]
direction TB
gitclient[Git client]
end
subgraph openproject[OpenProject]
direction TB
opgitlabintegration[GitLab integration] --- workpackagesmodule[Work packages module]
end
gil-01 TLSgil-02 TLSgil-03 TLS%%{init: {'theme':'neutral'}}%%
flowchart LR
api <-->|api-01| apiintegration[API integration]
subgraph externalintegreations[External integrations]
direction TB
apiintegration
end
subgraph openproject[OpenProject]
direction TB
api[API]
end
Note: Please see the API documentation for further information about all API endpoints.
api-01 TLSOpenProject makes use of technical cookies to identity the browser client and/or remember information such as 2FA login state. The core application makes use of these cookies:
| Cookie name | Description | Expiration | Security flags | Implementation |
|---|---|---|---|---|
_open_project_session (name is configurable) | contains the information about the logged in user as well as information stored between requests on the user's choices (e.g. the filters for costs are in part stored there) | Session |
autologin (name is configurable) | (Optional feature, requires opt-in under Administration > Authentication settings)
enables the user to automatically log in again after the session expired (e.g. because the browser was closed). It is set when the user checks the 'Stay logged in' box in the login form.
| Cookie 1 yearop2fa_remember_token | the presence of that cookie suppresses the need for the user to provide a second factor upon login for N days (configurable by administration) if the user selects to do so when entering the 2fa information. | N days (configurable) | secure
httponly
Samesite=Lax
encrypted | Code ref |Whenever a user in OpenProject is fully deleted, the system scrubs and removes all user master data, all functional assignments, and all references to a user in the change histories. All actions performed in the name of the user are being replaced with a singular "Deleted user" reference in order to maintain integrity of database references, such as being an author of a work package that remains. Finally, the user data itself will be deleted, removing all structural traces of PII in the system.
Note: Due to the user references changing, respective cache keys for information such as work packages or projects are invalidated automatically.
Note: Deleting a user account is a permanent action and cannot be reversed.
For more information on user account deletion, please see the user administration guide.
Note: Input created by a user such as text or comments cannot be deleted or scrubbed in an automated fashion. The content stays but will be referenced to the non-personal "Deleted User".
Note: Persons mentioned in text or shown in uploaded pictures cannot be deleted or scrubbed in an automated fashion. All references to persons in text or pictures need to be deleted either one by one or by deleting the project in total. Memory references in memcached might still refer to (invalidated) user data until it is being reassigned.
Note: Logfiles might retain personal data for the configured retention period of the logfile. See "D: Logging" above.