Can A Mobile Application use TrueVault to store JSON data without a "middleman" server? - truevault

I have been reading the documentation at https://docs.truevault.com/ but I am a little confused. I read this on the true vault site:
If you plan on using any of the server-side libraries, please ensure
any hosting environment you use is HIPAA compliant.
I took this to mean that TrueValut could support a standalone (client side only) mobile application architecture. Where the TrueVault API was the only server side interaction.
However my understanding of the documentation is that:
An API_KEY is required to register a new user.
Any API_KEY provides full access to all data vaults and JSON documents stored in TrueVault.
If both of these assumptions are correct that would mean it would be impossible to register new users directly from the client side app, forcing me to use a costly and resource intensive HIPPA compliment web server. The only way to get around this would be top hard code the API_KEY into the app, an obvious no go if that API_KEY can access all of my TrueVault data.
For my use case I have the following requirements for TrueVault for me to be able to consider using it (I would imagine these requirements are the same for anyone looking to develop a client side only healthcare application):
A user can sign up via the API directly from my client side app without requiring any sensitive keys or root auth data.
A user can authenticate using only the data they provided to sign up (username/email/password). My app is multi platform I cant ask them to remember their API keys to log in.
A user can Read/Write/Update/Delete data linked to their profile. They can not access any data from another user using their credentials.
Is TrueVault able to deliver these three basic requirements?
If the answer to this is "No" I would recommend you update this text on your website as there are not going to me any viable HIPPA compliment applications that can be supported by TrueVault without an independent server side interface.

I'm currently using AWS Lambda as a solution. Lambda is HIPPA compliant, more info here. Lambda is also a low cost solution.
Here is an example of the code I'm running on Lambda using Node.js.
var request = require('request-promise');
var _ = require('lodash');
function encodeBase64(str) {
return (new Buffer(str)).toString('base64');
}
var baseUrl = 'https://api.truevault.com/v1/';
var headers = {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
};
var req = request.defaults({
baseUrl: baseUrl,
headers: _.extend({
Authorization: 'Basic ' + encodeBase64('your api key:')
}, headers),
transform: function(body) {
return JSON.parse(body);
}
});
exports.handler = function(event, context) {
req.post('users', {
form: {
username: event.email,
password: event.password,
attributes: encodeBase64(JSON.stringify({
name: event.name
}))
}
}).then(function() {
context.succeed({user: user});
}).catch(context.fail);
}

In general, you are correct - if you include zero server-side processing between user and TrueVault, then the API keys will be public. At least, I don't know of any way to avoid this.
That being said, it is incorrect to jump to "any API_KEY provides full access to all data vaults and JSON documents stored in TrueVault." - that's not the case if setup properly.
TrueVault API keys are able to be narrowed in scope quite a lot. Limiting a key to only Write permission on {Vault#1}, a second key to only Read permission on {Vault#2}, a third key to allow uploading Blogs in {Vault#1&#3}, quite a few variations, a forth for deleting information from {Vault#2}, and on as needed. You can also limit permissions specifically to content "owned" by the API key (e.g. user-specific keys) Full documentation here.
There are also limited scope keys (set expiry time, usage count, limit to any of the prior permission scopes). Docs here.
TrueVault also offers user logins separate from API keys which may be better suited if your user are using login credentials. Docs here.
I'm still rather figuring out TrueVault myself (at time of writing at least) so be sure to research and review more for your needs. I'm still torn if the limited scoping is "good enough" for my needs - I'm leaning towards using AWS Lambda (or similar) to be a HIPAA compliant middle man, if only to better hide my access token generation and hide that my data is going to TrueVault and add some "serverless-server-side" data validation of sorts.

Related

Is it ok to store user's secrets in PropertiesService.getUserProperties()?

I am developing a Google Workspace Addon (standalone script) which will make REST API calls to external service and for that purpose it needs to provide an API key.
I request the API key input from a user and then store it in PropertiesService in the following way:
function onSheets(e) {
const userProperties = PropertiesService.getUserProperties();
const saved_api_key = userProperties.getProperty('api_key');
const api_key: string = saved_api_key ? saved_api_key : "";
const builder = CardService.newCardBuilder();
const apiKeyInput = CardService.newTextInput().setTitle('API Key')
.setFieldName('api_key')
.setHint('Enter your API Key')
.setValue(api_key);
const saveApiKey = CardService.newAction().setFunctionName('saveApiKeyFn');
const button = CardService.newTextButton().setText('Save').setOnClickAction(saveApiKey);
const optionsSection = CardService.newCardSection()
.addWidget(apiKeyInput)
.addWidget(button)
builder.addSection(optionsSection);
return builder.build();
}
function saveApiKeyFn(e) {
const api_key = e.formInput.api_key;
const userProperties = PropertiesService.getUserProperties();
userProperties.setProperty('api_key', api_key);
return CardService.newActionResponseBuilder()
.setNotification(CardService.newNotification()
.setText("API Key saved"))
.build();
}
Since userProperties are scoped to a current user it seems fine. But I have serveral problems with this solution:
Is this really safe? I mean it is stored in plain text so maybe there are ways to retrive it by other mailcious user?
The idea that by mistake I would use getScriptProperties() and thus leak one user's API key to all other users gives me nightmares. It is highly sensitive API key. It would cost a user tons of money if abused.
I read that some user's suggest https://cloud.google.com/secret-manager but I am not sure it's fit for this particular scenario. It would require one more external API call. It is not free. And lastly from what I underestand I would be sort of an owner of all of these secrets since I will be the owner of the Google Cloud project in which this API runs.
All I want is for the users to be able to store their keys safely, so that no one else including me can never access them.
What would you suggest? Thanks!
Is this really safe? I mean it is stored in plain text so maybe there are ways to retrive it by other mailcious user?
Security is relative. There's no such thing as absolute secrecy. Here are some attack scenarios:
Google employees or support may have unrestricted access
If a particular user installed a trigger, that trigger runs as that user and other users, if they can trigger the script and have edit access to the script, will be able to access the keys. A common scenario would be a installed edit trigger in a sheet. User B can access user A, if he can make a edit as well as edit the script. As mentioned in the comments by doubleunary, this is less of a problem in a published add on, as the source code is not accessible or editable.
Encrypting keys is a possibility. But, where would you store the decrypting key? You could ask every user to have a custom password for decrypting the key. But how many times are you going to make a API call? Would they have to enter the key every time? At what point does convenience overtake the need for secrecy?
The idea that by mistake I would use getScriptProperties() and thus leak one user's API key to all other users gives me nightmares. It is highly sensitive API key. It would cost a user tons of money if abused.
That is a possibility, but one that's easily avoidable by careful code review by yourself and your peers.
Those are the scenarios I could think of.
Related:
Securely Storing API Secrets used in Google Apps Script - Published Library

Node & GraphQL Auth

What is the recommended method of handling user authentication and token creation using Node/Graphql? I see a lot of tutorials out there that use a REST endpoint to authorize the user and generate the token.
While I'm new to the GraphQL scene, I don't see why you wouldn't use GraphQL for this.
For example, why not have a query like this which gets sent to a resolver that checks the user/pass and generates a token? :
mutation {
loginUser (
username: "YOURUSERNAME",
password:"YOURPASSWORD"
)
{
token
}
}
Is there a specific reason that the tutorials I've gone through haven't done it this way? Is there some sort of flaw in this method that I'm not aware of?
The official docs explain the reasoning a bit: https://graphql.org/graphql-js/authentication-and-express-middleware/
Reading between the lines a bit, it seems there isn't any official recommendation to not do this, but existing tools expect headers to be used and classic endpoints so this fits better.
If you start talking about OAUTH you're going to have to implement classic URLs anyways as well to complete that dance.

How to get Correct Subscription key for microsoft Face API for Nodejs?

I am using project-oxford inorder to use Microsoft API with nodejs. I am keep on getting error that ,
{"code":"Unspecified","message":"Access denied due to invalid subscription key. Make sure you are subscribed to an API you are trying to call and provide the right key."}
{"code":"Unspecified","message":"Access denied due to invalid subscription key. Make sure you are subscribed to an API you are trying to call and provide the right key."}
I have also regenerated my subscription key for my microsoft account and tried to access the code. Still I am getting the same issue. Spent lot of time to find my bug fixed, But I couldn't able to solve.
This is my nodejs code,
var oxford = require('project-oxford'),
client = new oxford.Client({SubscriptionKey});
client.video.trackFace({
url: path,
}).then(function (response) {
console.log('Response ' + JSON.stringify(response));
},function (error) {
console.log("Error"+JSON.stringify(error));
});
Please guide me to fix this issue.Thanks in Advance!!
You can obtain a key via the Microsoft Cognitive Services web site.
From what I can gather, you are using https://github.com/felixrieseberg/project-oxford, is that correct?
It seems that project requires one subscription key, which then is used for all API calls. I can't see any reasons it shouldn't work, if you have signed up for the subscription key for the Video API.
Given that the library you're using is built the way it is, it seems to me that you will only be able to use one API at the time, doing it the way you're doing it now.
Am I making any sense?
Actually Now I am getting output for the same code excepting that I was not able use the localhost URL [i.e., http://localhost:3000/uploads/img.jpg]. While using the url of webserver only then I am getting the output!!
Can anyone explain me the complete fact. i.e., I need to know whether I cannot use the localhost url. If I use so I am getting the error which I have posted in this question.

Getting customized message from GCM using Web push notifications

I'm using Web push notifications with Chrome, and they work great. But now I want to deliver a custom message in my notifications. I can have my Service Worker call out to my site to get content, as is done at https://simple-push-demo.appspot.com/—which is fine if I want every recipient to see the same message.
Is there any way to get either the recipient’s registration_id or the message_id that GCM returns? If I could get either of these and include them in the callback to the service, I could customize the response.
Also, any info on when we might be able to include a payload in the call to GCM?
The registration_id and message_id fields aren't exposed, but if the user is previously authenticated to your app, any fetch() to the server from your Service Worker will include credentials (and session information) which you can use to identify them.
If that doesn't work for your case, you can store user/session information in IndexedDB.
Payloads are coming soon—likely Chrome 50 or 51—based on the Web Push protocol. It's a bit of extra overhead and work to configure the (required) encryption.
It's possible, but I wouldn't do it since it's specific to GCM, while other browsers use other services.
You can either create a unique ID for each user (like we're doing in Mercurius) and store it in IndexedDB, or you can use the entire endpoint URL as an ID.
Here's the snippet to get the registration_id:
self.registration.pushManager.getSubscription()
.then(function(subscription) {
if (subscription) {
var endpoint = subscription.endpoint;
var endpointParts = endpoint.split('/');
var gcmRegistrationID = endpointParts[endpointParts.length - 1];
console.log(gcmRegistrationID);
}
});
P.S.: It returns a promise, so make sure your service worker waits for the promise to be resolved.

Detail of list without user authentication

I'm trying to get details of Foursquare list by PHP library:
$foursquare = new FoursquareAPI($key,$secret);
$list = $foursquare->GetPublic('lists/'.$listId);
But everytime gets this error:
string(7672) "{"meta":{"code":200,"errorType":"deprecated","errorDetail":"Please provide an API version to avoid future errors.See https:\/\/developer.foursquare.co ... "
When I debug it, library calls this URL: https://api.foursquare.com/v2/lists/ with these params: Array ( [client_id] => <client_id> [client_secret] => <client_secret> )
But when I try this API method in Foursquare API Explorer I see that, this URL is calling: OAuth token automatically added. https://api.foursquare.com/v2/lists/<list_id>?oauth_token=<token>&v=20111205.
In lists doc is Requires Acting User: No, so I'm confused. Is it possible to call this function without authenticating user?
It would be nice, because I want to add places from my list (favourite restaurants) to my page on Google map in Contacts. It would be useful for our clients.
The error you are seeing is unrelated to the list endpoint you are requesting or the state of authentication. It is a warning that the library you are using is currently not following versioning best practice for Foursquare. You can read more about it here.
As for the list there should be a response object at the same level as the meta object.

Resources