Security question - Google Sheet credentials.json access - google-sheets

I have an outside developer who is asking for a credentials.json file in order to write to a Google Sheet.
I'd like to restrict the developer's access to just a single file, so I've made a service account with access to just that sheet. However, I'm quite unfamiliar with service accounts and the amount of access they allow. For example, it's unclear to me if the service account will have access to any files/scripts/processes outside of the single sheet shared with it and the API project in which it lives. Is there a way to check that? Or any documentation on best practices for granting this kind of access? (Or really, any kind of "Google APIs" for Dummies I could read.)
For context, I have basic programming experience, but top out at Javascript in AppScripts.

Related

Is using the Google Sheets API to scrape my own spreadsheet against the terms of service?

I've been writing a utility to sync a Google Sheets (which the organisation I'm a part of owns) to an SQL server, mostly for compatibility reasons while we develop our new backend.
My concern, however, is that the Google API Terms of Service states as follows:
Unless expressly permitted by the content owner or by applicable law, you will not, and will not permit your end users or others acting on your behalf to, do the following with content returned from the APIs:
Scrape, build databases, or otherwise create permanent copies of such content, or keep cached copies longer than permitted by the cache header;
https://developers.google.com/terms#e_prohibitions_on_content
In my case, is the 'content owner' myself, since I own the file on Drive, or Google, as it's stored on their servers? I'd really rather not get myself banned from Google, because we keep quite a bit of data in Drive.
I'm linking from official Google ToS which states that:
As our Terms of Service state, "You retain ownership of any intellectual property rights that you hold in that content. In short, what belongs to you stays yours."
Here is the link

What is the role which allows to use GCP APIs (such as Drive, Sheets, etc)?

I want to use Drive & Sheets API from Python3.
I tried to create a service account in GCP console, but it said You already have credentials that are suitable for this purpose, without telling me what role of GCP makes it suitable.
Now I want to find and add the role to my favorite service account. I do not want to create a new one, nor use the already-suitable ones.
What is the name of the role which allows using Google APIs?
I think this is confusing and poorly explained in Google's documentation but IAM and OAuth scopes are mostly (now) complementary technologies. I consider IAM to refine or provide more granular, account|credential-specific scopes
Scopes came first and IAM came later.
IAM -- actually Cloud IAM -- applies only to Google Cloud Platform (GCP) services.
OAuth scopes exist for all Google's APIs (including those of GCP).
https://developers.google.com/identity/protocols/googlescopes
In your case, Drive and Sheets are part of G Suite and not included in Cloud IAM. There are thus no IAM roles for you to assign to your service account that apply to these services.
For GCP services, it is customary (though seemingly redundant) to use both IAM and scopes.
Often you'll see https://www.googleapis.com/auth/cloud-platform used as something of a catch-all|default scope.
UPDATE: In retrospect, I should add a qualifier to this, OAuth scopes are effectively redundant for service accounts. In the case of a human|user-based OAuth flow where the end-user is delegating authority, the scopes remain relevant as they summarize the permissions for the end-user to review before granting to the code.

Using Azure AD to secure a aspnet webapi

I'm writing an application that will be the backend for a react website. The website is to be used by our customers, but we will fully control the permissions of the user. We have decided to use Azure AD to secure requests, but will also be exposing the API for end users to use directly if desired.
My understanding is in Azure AD I will have to create an application that will allow web based implicit authentication (for the react site), as well as a native application that will allow a dameon based application to authenticate to the API.
This I believe means I will have two audience ids in my application.
I'm trying to get claims to include groups, and I can see if I edit the meta data of both applicaitons in azure AD to include "groupMembershipClaims": "SecurityGroup" I can get claims with the group IDs in, but no names.
I think I can also use appRoles to set roles the application uses, but I've yet to get that to come through as claims in the JWT, but I'm assuming it can be done, however I'd need to setup the roles on each applicaiton, then add the user twice which isn't really ideal. I also think that because my app is multi-teanated that external users could use this to set their own permissions, which isn't what I want to do.
Sorry I'm just totally lost and the documentation is beyond confusing given how frequently this appears to change!
TLDR: Do I need two applicaitons configured in azure ad, and if so whats the best way to set permissions (claims). Also is oAuth 2 the right choice here, or should I look at open id?
Right away I gotta fix one misunderstanding.
Daemon apps usually have to be registered as Web/API, i.e. publicClient: false.
That's because a native app can't have client secrets.
Of course the daemon can't run on a user's device then.
Since that's what a native app. An app that runs on a user's device.
This I believe means I will have two audience ids in my application.
You will have two applications, at least. If you want, the back-end and React front can share one app (with implicit flow enabled). And the daemon will need another registration.
I'm trying to get claims to include groups, and I can see if I edit the meta data of both applicaitons in azure AD to include "groupMembershipClaims": "SecurityGroup" I can get claims with the group IDs in, but no names.
Yes, ids are included only. If you need names, you go to Graph API to get them. But why do you need them? For display? Otherwise, you need to be using the ids to setup permissions. Names always change and then your code breaks.
I think I can also use appRoles to set roles the application uses, but I've yet to get that to come through as claims in the JWT, but I'm assuming it can be done, however I'd need to setup the roles on each applicaiton, then add the user twice which isn't really ideal. I also think that because my app is multi-teanated that external users could use this to set their own permissions, which isn't what I want to do.
Your thoughts for multi-tenant scenarios are correct. If you did want to implement these though, I made an article on it: https://joonasw.net/view/defining-permissions-and-roles-in-aad.
Why would you need to setup the roles in multiple apps though? Wouldn't they only apply in the web app?
If the native app is a daemon, there is no user.
Overall, I can see your problem. You have people from other orgs, who want access to your app, but you want to control their access rights.
Honestly, the best way might be to make the app single-tenant in some tenant which you control. Then invite the external users there as guests (there's an API for this). Then you can assign them roles by using groups or appRoles.
If I misunderstood something, drop a comment and I'll fix up my answer.
Azure AD is of course a powerful system, though I also find the OAuth aspects confusing since these aspects are very mixed up:
Standards Based OAuth 2.0 and Open Id Connect
Microsoft Vendor Specific Behaviour
ROLE RELATED ANSWERS
This is not an area I know much about - Juunas seems like a great guy to help you with this.
OAUTH STANDARDS AND AZURE
I struggled through this a while back for a tutorial based OAuth blog I'm writing. Maybe some of the stuff I learned and wrote up is useful to you.
AZURE SPA AND API CODE SAMPLE
My sample shows how to use the Implicit Flow in an SPA to log the user in via Azure AD, then how to validate received tokens in a custom API:
Code Sample
Write Up
Not sure how much of this is relevant to your use case, but I hope it helps a little on the tech side of things...

Can we use Google Spreadsheet as a backend database

I am trying to develop an application, where I where fetching data from multiple clients related to some transactions. Now I want to make some analysis using the Google Spreadsheet. Is there any way by which I can achieve this using the ASP.Net MVC(using C#). Google provides OAuth and When I implement the code and when I am trying to send the data to Google spreadsheet which I receive form the clients. However, when I am doing that, for every new client, Google asks for login credential. Client enter their own credentials, and the Google sheet instead a common sheet, client own sheet is used. Thus, my purpose is not solved. Is there any way possible to do this. I does not seem to find proper documentation on Google as well. Please provide some suggestions to implement this. Thanks in advance.
This can be done very easily if you just want a read only database.
You must publish your Google Sheet to the web and, from its url, copy its id.
For example my sheet has this url: https://docs.google.com/spreadsheets/d/1IHF0mSHs1HdYpIlIzYKG3O8SnAhKU_a6nEJSz04Togk/edit
The long alphanumeric string in the middle is my sheet id. Copy it and place it instead of XXXX in the following url, as follows:
https://spreadsheets.google.com/feeds/list/XXXX/1/public/basic?alt=json"
So the final url would look like this:
https://spreadsheets.google.com/feeds/list/1IHF0mSHs1HdYpIlIzYKG3O8SnAhKU_a6nEJSz04Togk/1/public/basic?alt=json
Then you can simply access this url and get all your data as json.
Using jQuery:
var $url = 'https://spreadsheets.google.com/feeds/list/1IHF0mSHs1HdYpIlIzYKG3O8SnAhKU_a6nEJSz04Togk/1/public/basic?alt=json';
$.getJSON($url,function(data){
alert(JSON.stringify(data.feed.entry));
});
You will get a long json structure. The relevant data is in data.feed.entry. There you'll have many entries. On each one you'll have a "content" property and within it, a "$t" one. These will give you all the cells.
So for getting the first row, you will have to get data.feed.entry[0].content.$t.
Hope it helps.
This can be accomplished using Google Apps Script. In particular, you can achieve this with a "bound" script in Google Sheets (i.e. a script that was created in the context of the sheet that you wish to create as the "backend") that you then publish as a "web app" script. When you publish it, you can make it execute with the authority of the owner of the spread sheet (rather than the authority of the user who invokes the url), which will not require the end user to explicitly authorize themselves (since it is the script publisher's credentials, not the user's credentials, that are being used).
It should be noted that, while this (and generally building on top of Google Apps Script) is a reasonable approach for small-to-medium apps, you'll probably find using Google Cloud Platform (and, in this particular case, the Cloud Datastore) as the better, more scalable solution for small-to-large apps. That is, if you are prototyping or creating an internal tool that is unlikely to catch fire overnight, I'd go with whichever approach you find more convenient / simpler; if you are creating an app that could potentially experience a "success disaster", I'd go with Cloud Platform, instead.
If your sheet is public, you can do it withouth authentication. You can use google API Visualization with the query language or use the Google Sheets API.
But if your sheet is private, it is mandatory the use of OAuth2 authentication through service account credentials.
In order to do that, you have to create a service account (with owner of the project role for example). Then you have to download the client_secret.json file which will be the one you use in your code.
Finally you have to share your spreadsheet with the email you get in this file. Look in the file and you will see it.
I have made a tutorial. You can visit at http://edba.xyz/google-sheets-as-database. It is mainly based in PHP but it is easily trasportable to
other languages.
I have recently been developing a website using google sheet as backend. It is great. The speed is also appreciable.
I have integrated the custom backend which I wrote on google apps script with my Django app. So now my website stores the user information on google sheets. The google sheet code and Django app interact via Rest API which can be easily developed using doGet() and doPost() in apps script and python request on the Django side. Once the necessary structure is built( it does take some time tweaking if you are new) but then it works as a great database for your website.
Google spreadsheet is a great solution for quick prototyping database and even in some cases for production use.
People have already realized the potential and there are many tools today for turning your Google spreadsheet into a backend api
There are couple of libraries such as node-sheets for obtaining a json feed from a Google spreadsheet (read-only)
Also, if you need a complete standalone service you have some paid options like
https://sheetsu.com
And also open source options such as
https://github.com/scheduleonce/express-sheets
This can be installed on any cloud provider via Docker and you can point it to your spreadsheet and it will dynamically turn it into an api.
So if, for example, your spreadsheet has the following sheets:
| articles | products | users |
It will automatically create the 3 endpoints
GET /articles
GET /products
GET /users
It is suitable for read-only apis (you update the spreadsheet directly, not through code) that don't need to be changed too often (although you can control the update interval)
You can use Kodem.io.
Google Sheets As Backend allows you to do CRUD requets using Google Sheets.
Disclaimer: I work at Kodem

Decoupled Web APIs on Azure (Architecture Advise)

I'm working for a non-profit that is trying to create a collection of services that will allow them to do a few things:
Create/Manage Users
Create/Manger Competitions
Create/Manager Events(a Competition is made up of many Events)
Logistics
Etc.
Here are some of the requirements:
Host on Azure
Accounts are created using the user's own email address (can be any domain)
Each service must be independent of each other
System should be accessible from anywhere(browser, mobile app, etc.)
Once a user logs in, access to other systems should be available(if needed or depending on permissions)
-services can talk to each other(we've successfully done a POC on this using Azure Active Directory)
I've spent some time researching the possible ways to tackle this, including looking at articles like this:
http://bitoftech.net/2014/10/27/json-web-token-asp-net-web-api-2-jwt-owin-authorization-server/
It sounds like JWT is the way to go, but I want to make sure that this architecture approach lends itself to flexibility down the road. I'm willing to learn/user any technology as long as it plays along .Net, Web Api, and MVC.
My initial idea was to set each "system" as a Web API, which is pretty straightforward. My concern is authentication/authorization. The million dollar question then becomes:
How can I authenticate a user on a browser/mobile/desktop app and then make use of the other services(APIs), where each service can verify if the user is authenticated independent of other services.
For example, lets say I am using the web app(browser) and register as a user(using User service) in order to register for a competition(Competition service). what kind of technologies/architecture would need to be used for both services to use the same authentication mechanism?
I am not new to MVC or Web API but I am to a scenario like this, so all help or advice is greatly appreciate it. For any that are interested, this is the non-profit: http://worldjumprope.org/
They are doing some cool stuff in terms of outreach and spreading the love for jump rope. Their goal is to be able to help people all around the world and provide a way to for them to come together and compete. They've been doing it for years, growing each year, all for free and out of pure passion for the sport. Help me help them!
Azure Active Directory can help you with your need.
About the security/Auth mechanism, simply put, it is like you get a token from Azure Active Directory to be able to use it to do authentication for a certain Audiences/Tenants.
And in your architecture, when you acquire a Token, you can specify if you are going to use it against a certain audience or it will work for a list of audiences or all audiences in a specific tenant or in a multi tenant scenario.
Here is a link to a video about AAD Single Sign on:
https://azure.microsoft.com/en-us/documentation/videos/overview-of-single-sign-on/
You can download the AAD Solutions arcutecture from here:
http://www.microsoft.com/en-us/download/details.aspx?id=45909
Also maybe worth looking at Identity Server - https://github.com/IdentityServer/IdentityServer3.
Same concept as Azure AD in terms of tokens, but perhaps with greater options for what you choose as a data store for your user information.
There are lots of demos and source code on the site, particularly around the different types of authentication flow \ service to service authentication

Resources