Best Practice to Store Keys in Google Apps Script - google-apps-script

I would like to inquire for best practices in storing keys within the Google AppScript environment.
Currently, while I am prototyping, I just store the keys as local variables in the file where it is used. This key is used by all users of my App Script regardless of their domains.
Moving forward however I would like to safekeep this key in a more reliable storage. And would like to ask for advice on how to best safekeep these keys.
Currently, I am thinking of :
Using PropertiesService.getUserScriptProperties().setProperty(key,value) as this is shared by all users.
as part of the manifest? Is there a way to add userData in the contextual and homepage triggers?
Or just keep using local variables as the code is not visible to the users anyway?
Thank you all in advance.

I understand that you ask about the best way to store a static key that would be retrieved by anybody who runs your Apps Script project, being indifferent to its domain. I also assume that the script is being run as the owner (you) and that the final users shouldn't be able to read the key, please leave a comment if that isn't the case. With this situation you have the following approaches:
The straightmost approach would be to use the Properties Service. In this particular scenario the key should be accessible to anyone executing the script, therefore PropertiesService.getScriptProperties() is the way to go (you can learn more about other scenarios here).
As an alternative you could store the key in your own database and use the JDBC Service to access it. This method is compatible with Google Cloud, MySQL, Microsoft SQL Server and Oracle databases. Here you can learn more about reading from a database.
Another possible choice is the Drive API. You could take advantage of the application data folder since it is intended to store any files that the user shouldn't directly interact with. For this option you would need to use the Advanced Drive Service on Apps Script.
Please be aware that an admin from your domain could access (or gain access) to the stored key. Also please check the quota limits to see if it fits your usage.

As you may have noticed, the PropertiesService provides several methods for storing key/value at the document's level, user's level or script level:
getDocumentProperties()
getUserProperties()
getScriptProperties()
I'd recommend to store a property based on who needs access to it. If only the authenticated user should have access to a property (such as for example a setting relevant only to its accounts, like it's locale language), go with the UserProperties. Contrary, if the property is relevant to a document (Google Docs, Google Sheets, etc.) go with the DocumentProperties.
With this said, I wouldn't recommend using the ScriptProperties in general. The main reason being that quota applies to the PropertiesService (see table below). This means that as your add-on gets more and more users, you will hit the quota limit quite rapidly.
| Service | Consumer accounts (e.g. #gmail.com) | Google Workspace accounts |
|--|--|--|
|Properties read/write | 50,000 / day | 500,000 / day |
Source: https://developers.google.com/apps-script/guides/services/quotas
Depending on your use case, you might also be tempted by alternatives to the PropertiesService:
using local variables in your code - as you mentionned
using the CacheService - which store data for a limited period of time.
making request to a distant server where you could query your own database.
We heavily rely on the latest at my company, thanks to the UrlFetchApp service. The main reason being that it allows us to pull a user profile from our database without making updates to the codebase.

Related

Shared Data Extension to BigQuery (GCP)

I`m quite new at using saleforce but I have been able to use Cloud Data Fusion recently to transfer information from a Data Extention to a table in Big Query.
Know I would like to do the same thing but with a Shared Data Extension, meaning that (possibly) features like the external key of the D.E would not exist because the D.E is shared by different Business Units (B.U) and also, I think I would have a problem by dealing with the authentication (Client ID – Client Secret - ) because again, is a Shared Data Extension.
Thank you very much for any insight on this matter.

is there any database for Google apps script/workspace add-on

I am working on a google workspace add-on for gmail. As part of it, I want to store and index some data, so that it can be later aggregated/enriched for insights.
I don't want to use some external(outside-google-workspace) database as it will have data privacy and security implications. So, I want to keep that data within the safe precincts of the user workspace.
Is there any database service within the google workspace for the above mentioned requirements?
PS: I am already aware of Properties service which can store configurations. The data i want to persist is definitely more than that.
There is no such database.
The closest alternatives, as already mentioned, are PropertiesService, which has obvious limitations, and Google Cloud SQL databases, which live in Google's cloud but is not part of Google Workspace.

Synchronization across different systems

I have 2 systems let's call them i and j. Each have it's own database.
Each have a registration page, where a user is inserted in a user table.
What is the best way to synchronize both tables, where if any user registers at system i it will be also registered at system j.
Notes:
I cannot read from each other databases directly.
I can do small changes in the code if needed and it will not affect the system performance or natural behavior.
I can create API's for both systems if needed.
I can add any tables or fields if needed.
I can create any cron jobs unless it will affect the performance of the system or server.
I'm using cPanel.
Technologies:
MySQL
PHP
REST API's
The fact that you list cpanel as a technology shows you're working with an inflexible budget hosting vendor. So it's unlikely they'll cooperate in setting up background tasks (cron jobs) to merge your user tables behind the scenes. (cpanel isn't a technology: it's a system administration user interface provided by hosting vendors who don't trust their customers' skills.)
So. you should design and implement a REST API in the code of both your apps to perform user registration and authentication tasks. You didn't show us the details of your app, so it's hard to design it for you. Still it seems likely you'll have to implement these operations:
PUT user
DELETE user
GET user
POST user to validate a user's password, etc. (Don't use GET to pass secret information: GET request parameters go into server logs.)
PATCH to update details of a user.
If you get the API working, whenever you create/retrieve/update/delete user information in one app, you'll use the API to change it in the other.
Your best bet would be to create a third app just for user management, and have both your existing apps use it. That way you're sure to have one coherent source of truth about users. But you can do it just within two apps.

Access 2007 security options to avoid redistribution

My question is as follows. When I recieve a usage fee for an application I developed in Access 2007 I send out the application to my client, but how do I make sure that the client won't simply copy the database and redistribute it. Thus letting the client's client avoid the usage fee for the application.
I have put a 128-bit encryption on the application to secure the data in the tables and also converted it from a .Accdb to .Accde to secure the forms, reports, query's and VBA.
Also, I let them sign a legal document in which it states that the application cannot be redistributed unless authorized by me, but of course I'd rather they couldn't even if they tried.
What are my options here? I thought about linking a license code (handmade by me) to a certain MAC-Address that I can retrieve with VBA. And only making the database usable in case they match. But would this even work and is it easy to bypass?
Any help would be greatly appreciated,
thanks in advance for any suggestions/replies.
Edit: Thanks Dork Programmer for your reply.
In the end I chose to go for the drive volume number to give access to the application. I am aware that this changes when the disk is formatted and there is a slight possibility that it is not unique, however I believe this will have to do as I am unable to retrieve the manufactures hard drive serial number (which would be unique)
In conclusion; the client wil give me their drive vol number, I then add this to a table that holds these numbers. I then apply all my security measures and send the client the app. When the application opens the app will only be usable if a match is found between the clients disk vol number and the values in the table, else it will close the app. Should a client decide to format his/her disk or remove it they could then contact me and I'd add the new number to the approved numbers table and send them the app back.
I just sharing what I did on my ms-access application
First, I create some form with the VBA code inside to enter the unique code
Then I create some Hidden table to store the unique code and also to store the IP address/Computer name that database located.
Based on my experience, this method is quite enough effective to avoid user copying the database or moving it to another computer.

Tracking data access

Backstory
I work for a company that has an online site that allows user to text personal information for collection. We collect the data, and make it available online. Users can choose to share the data with other users.
Going Forward
At some point, this may become classified an FDA-governed medical tool. In anticipation, we'd like to have in place a logging system that shows each time someone accesses our users' data, whether it be the user themselves, another authorized user, or a support person.
Current Architecture
We are currently running Ruby/Rails, and using a MySQL database. The personal information is encrypted in the database.
Data Access for Support
Today, support personnel can access data one of three ways:
admin site The admin site is limited to whatever screens we develop. While we don't currently, we could easily add logging to keep an audit trail of who accessed which data using the admin tool.
sql client I use MySQLWorkbench to access production. However, when connected this way, all personal information (user name, cell number, etc), is encrypted.
Ruby Rails console - Finally, support can log into one of the production boxes and use the Ruby/Rails console from command line. Ruby will decrypt the data, so we can do some simple things such as
u=User.find_all_by_state('active')
and it will return the recordset of all users with state='active', and decrypt their personal information in the resultset.
Holy Grail
logging
easy access for support
I'd love to be have a way to allow easy support access (once authenticated) to the data, but would log everything that is accessed (read or updated). That way, if I'm checking out my buddy's ex-wife's data for example, it gets logged to a place where I can't get in and clean it the audit trail. (See Google firing Gmail employee for an example of employees breaching the data policies).
Anyone have ideas, thoughts, experiences, suggestions with this issue?
hey devguy. This was a issue for me a couple months back. We ended up centralizing our mysql queires so that we could start to track all information coming in and out. Unfortunately the class I wrote is in PHP but the idea behind it could make it very easy to start logging.
https://code.google.com/p/php-centralized-mysql-controller/
Try stored procedures. Make all code use the stored procedures for CRUD activities. This defines an API that your developers can use while business rules are global enforced (don't return entire SSN values, but only last 4 digits, etc).
This serves as the basis for an external API as well.
If you want logging/auditing, you put it in the procedure.
This protects you from everyone except the DBAs.