Skip to content

Product Architecture and Security

Our product architecture overview and security guiding principles are publicly shared.

Security Overview

Development

  1. Production data is kept separate from development data and it doesn't leave production servers
  2. DoubleGDP does not develop on real customer data and follows the client’s guidelines on data access
  3. We encrypt communications (SSH, HTTPS) to development servers.

Production

  1. We encrypt communications (SSH, HTTPS encryption) to our production servers.

  2. End-to-End encryption through CloudFlare.

  3. We encrypt files at rest using S3 server side encryption. SSE-KMS. https://docs.aws.amazon.com/AmazonS3/latest/dev/serv-side-encryption.html

  4. Heroku postgrees encryption: https://devcenter.heroku.com/articles/heroku-postgres-production-tier-technical-characterization#data-encryption (Database is encrypted at the block-level storage encryption)

Sensitive File Handling

  1. Engineers are sometimes given access to files containing sensitive information through google docs and following Google encryption procedures: https://services.google.com/fh/files/misc/google-workspace-encryption-wp.pdf

  2. Files are access using HTTPS

Vulnerabilities.

  1. As part of our deployment process, we monitor for vulnerabilities and address them promptly.

Engineer Training on Privacy

Starting January 2021, Engineers will be required to attend data privacy training.

Application Permissions restructure.

  1. As part of engineering efforts towards product security improvement, we have refined application permissions following the guidelines below:

  2. We have application permissions under app/policies/.

  3. Within app/policies we have submodules that reflect different modules we have like payments, tasks, communities

  4. permissions are defined with module name and associated roles and permissions as an array e.g community: {admin: %i[can_update_community]}, payments: {admin: %i[can_create_plan_payment]}.

  5. Within each specific policy module example CommunityPolicy we have a permission checker against a specific permission list in this case it checks for community permissions. ` user_permissions = permission_list.dig(:community, user.user_type.to_sym, :permissions) return false if user_permissions.nil?

user_permissions.include?(permission.to_s)`

  1. The policies are invoked from either queries or mutations, passing in a current user user_type attributes and the permission to check against. Example: return true if Communitypolicy.new.has_permission(context[:current_user].user_type, :can_update_community)

  2. To ensure backward compatibility, we have this check as first rule and older check as second return true if context[:current_user]&.admin?.

  3. For better permissions management and extensibility, we define all permissions in app/policies/permissions.yml file and read and initialize them in ApplicationPolicy PERMISSIONS = YAML.load_file("#{::Rails.root}/app/policies/permissions.yml") @permission_list = PERMISSIONS.deep_transform_keys!(&:to_sym)

  4. Application permissions for diffent modules can be found in this file https://gitlab.com/doublegdp/app/-/blob/master/app/policies/permissions.yml

Sample Current Roles and Permissions for different modules.

Module Permissions Module Permission
Form -[ ] can_see_menu_item
-[ ] can_create_category
-[ ] can_update_category
-[ ] can_delete_category
-[ ] can_create_form
-[ ] can_update_form
-[ ] can_create_form_properties
-[ ] can_update_form_properties
-[ ] can_delete_form_properties
-[ ] can_create_form_user
-[ ] can_update_form_user
-[ ] can_update_form_user_status
-[ ] can_create_user_form_properties
-[ ] can_update_user_form_properties
-[ ] can_view_form_entries
-[ ] can_view_form_form_submissions
-[ ] can_view_form_user_properties
-[ ] can_fill_a_form
-[ ] can_edit_a_form
-[ ]can_view_own_forms
-[ ] can_access_forms
-[ ] can_access_forms
-[ ] can_view_form_usernote
Payment Plan -[ ] can_cancel_payment_plan
-[ ] can_create_payment_plan
-[ ] can_fetch_community_payment_plans
-[ ] can_fetch_plan_statement
-[ ] can_fetch_user_payment_plans
-[ ] can_send_payment_reminder
-[ ] can_transfer_payment_plan
-[ ] can_update_payment_day
-[ ]can_update_payment_plan
-[ ] can_view_menu_list
Entry Request - [ ] can_see_menu_item
- [ ] can_access_logbook
- [ ] can_create_entry_request
- [ ] can_update_entry_request
- [ ] can_deny_entry
- [ ] can_grant_entry
- [ ] can_add_entry_request_note
- [ ] can_view_entry_requests
- [ ] can_view_entry_request
- [ ] can_update_invitation
- [ ] can_go_through_guest_verification
- [ ] can_invite_guest
Plan Payments - [ ] can_access_all_payments
-[ ] can_cancel_plan_payment
-[ ] can_create_plan_payment
-[ ] can_fetch_payment_receipt
-[ ] can_fetch_payment_stat_details
-[ ] can_fetch_payments_list
-[ ] can_view_menu_list
-[ ] can_see_menu_item
Land parcel - [ ] can_see_menu_item
- [ ] can_create_land_parcel
- [ ] can_fetch_house
- [ ] can_fetch_land_parcel
- [ ] can_fetch_land_parcels
- [ ]can_fetch_land_parcels_with_plans
- [ ] can_merge_land_parcels
- [ ] can_update_land_parcel
- [ ] can_view_all_land_parcels
-[ ] can_create_point_of_interest
-[ ] can_create_point_of_interest_image
-[ ] can_delete_point_of_interest
User -[ ] can_update_user_details
-[ ] can_merge_users
-[ ] can_import_users
-[ ] can_send_one_time_login
-[ ] can_access_all_users
-[ ] can_view_own_profile
-[ ] can_edit_own_profile
-[ ] can_get_substatus_count
-[ ] can_get_substatus_distribution
-[ ] can_view_admin_users
-[ ] can_get_user_count
-[ ] can_get_users can_get_users_lite
-[ ] can_see_menu_item
Email Template - [ ] can_see_menu_item
- [ ] can_access_email_template
- [ ] can_create_email_template
- [ ] can_update_email_template
- [ ] can_view_email_template_variables
- [ ]can_view_email_templates
- [ ] can_view_email_template
Transaction -[ ] can_create_transaction
-[ ] can_revert_transaction
-[ ] can_fetch_accounting_stats
-[ ] can_fetch_transaction_summary
-[ ] can_fetch_user_transactions
Subscription Plan - [ ] can_create_subscription_plan
- [ ] can_update_subscription_plan
- [ ] can_fetch_subscription_plans
Gate Access -[ ] can_see_menu_item
Campaign - [ ] can_access_campaign
- [ ] can_create_campaign
- [ ] can_delete_campaign
- [ ] can_create_campaign_through_users
- [ ] can_remove_campaign_label
- [ ]can_update_campaign
Community -[ ] can_see_menu_item
- [ ] can_update_community_details
- [ ] can_view_community_details
SOS - [ ] can_access_sos
- [ ] can_raise_sos
- [ ] can_cancel_sos
Label - [ ] can_create_label
- [ ] can_delete_label
- [ ] can_merge_labels
- [ ] can_update_label
- [ ] can_create_user_label
- [ ] can_update_user_label
- [ ] can_fetch_all_labels
- [ ] can_fetch_label_users
- [ ] can_see_menu_item
Note - [ ] can_create_note
- [ ] can_see_menu_item
- [ ] can_update_note
- [ ] can_set_note_reminder
- [ ] can_assign_note
- [ ] can_bulk_assign_note
- [ ] can_create_note_comment
- [ ] can_update_note_comment
- [ ] can_delete_note_comment
- [ ] can_fetch_flagged_notes
- [ ] can_fetch_task_by_id
- [ ] can_fetch_task_comments
- [ ] can_fetch_task_histories
- [ ] can_get_task_count
- [ ] can_get_task_stats
- [ ] can_get_own_tasks
- [ ] can_fetch_all_notes
- [ ] can_fetch_user_notes
- [ ] can_view_create_task_button
- [ ] can_view_create_sub_task_button
- [ ] can_access_tasks
- [ ] can_access_processes
- [ ] can_delete_note_document
- [ ] can_resolve_note_comments