I'm working with the Google+ Domains API using a service account for domain wide delegation. Unfortunately, we're having difficulties with our client regarding the authorization model, because in theory we have access to all G+ data (even from the CEO etc..), while they would like to exclude a group of people.
Is this possible? Otherwise, only thing is to expect the developers to not abuse of their rights?
Not possible. You could use regular 3legged during development (store each user's permissions) and switch to domain-wide at the end under client supervission. Then leave the appengine without any developers on your side, only one client account that has control and gives you permission to develop as needed later.
Related
I'm adding an external identity provider, Azure multi-tenant, as a login option. I have local accounts right now and they know nothing about Azure AD users.
I want to create an Azure Enterprise App that other tenants can use to set up SSO using OpenID Connect. Also I want the app to support User Provisioning by setting up a SCIM API.
I can't really find any documents on how to handle linking Azure AD users with the existing accounts in my IDP. I've seen examples where users can login using their local account, authenticate with Azure, and then their local account is updated to have the Azure AD User ID. This approach still seems pretty manual. Another thought was to have a step in the login journey, where if no local account has the Azure AD User ID then find a local account with the same email. I don't like this approach either since the emails might not always match. Is there an approach where an admin can automatically link all accounts with a sync or upload?
SYSTEMS
First it's worth clarifying roles:
Role
Details
Authorization Server (AS)
Your UIs and APIs receive tokens from this. It is where accounts and linked accounts are stored. It is where you use SCIM to update account records. It is where you apply account linking logic.
Identity Provider (IDP)
There can be multiple of these. When your apps call the AS it manages connections to them, and exchanges IDP tokens for AS tokens that are returned to apps. It is not usual to use SCIM against an IDP.
You are using IdentityServer as the AS so your UIs and APIs will continue to use IdentityServer tokens and remain simple. Meanwhile Azure AD will become an alternative IDP. So on the data side of things your architecture is in a good place.
AUTHENTICATION ACTIONS
I would aim to solve your problems via custom authentication actions, and to design this in a vendor agnostic way. Not all providers support these concepts, but IdentityServer has some pretty good extensibility features, so hopefully it has what you need.
A bit of code, configuration and technical investigations in IdentityServer feel like the correct direction, with no complexity added to your applications. I will describe techniques in terms of Curity (where I work), but the same principles can apply to any system.
USERNAME AUTHENTICATOR
A great way to deal with user specific differences is to make the initial screen prompt only for an email. See this example for how that looks. Later, when authentication has completed, you could set a cookie so that this screen is not shown on subsequent logins.
Then, before asking for credentials, apply some scripted logic, eg to look up existing account attributes, and decide how the user should authenticate. You might decide to route unknown users to Azure AD or do something based on business partner email suffixes.
DATA UPDATES
Something simple that might work in advance of adding Azure AD support is to assign all users a Tenant ID, and perhaps existing users get a Tenant ID of 1. Only those users are allowed to sign in with Identity Server - all others have to use Azure AD.
SCRIPTED LOGIC AND ACCOUNT LINKING
For a worked example of how this looks, see this Account Linking with Facebook tutorial. In this example the objective is to update the main account with a new linked account. This account linking doc may give you some additional ideas for your scenario. It should be possible to run custom logic before triggering authentication or once your have the Azure IDP attributes.
INVOLVE THE USER IF NEEDED
It may also be useful to present a custom screen to ask the user if they have an existing account when they first login via Azure AD. If not then an Azure AD login can create the primary account in IdentityServer data in addition to a linked account.
USERS AND PARTNERS
How users onboard is interesting, and discussed in this detailed article. I always start by getting a feel for the type of assets involved:
Type
Description
Personal Assets
You allow any user to sign up and they only have access to their own assets
Corporate Assets
Users are provisioned by an administrator, eg a banker is granted access to financial data according to business rules
In your case it feels like users are from the second category, so to enable a user to fully sign up you need data from the partner, either fed in manually or by getting them to call your API, before you can assign the user the correct tenant ID. This might eventually result in TenantID=23, but there is nothing to stop you initially allowing users to onboard and placing them in a default TenantID=0 bucket.
Ultimately this all comes down to data, claims and API authorization. Eg APIs could return certain data to TenantID=0 users but only return privileged data to users whose tenant ID has been asserted by an administrator. Not sure if these thoughts of mine match your scenario but hopefully they provide a useful hint or two.
SUMMARY
Reliable account linking is tricky, but it should be solvable via the building blocks of the Authorization Server, using the above techniques. The end result should be deterministic user data, with no duplicate users.
I'm trying to set up a Service Account that can access the GMail API, but for security purposes I want it limited to only a single mailbox (I don't want the development team to have full access to all mailboxes in the organization.)
My understanding of how Google handles service accounts and permissions is limited. I can't seem to find specific details about how this would be set up. I have set up a service account with client ID and secret. And I have associated that with an API client that has the GMail read-only scope. But how does that get associated with a specific mailbox? I do see a setting that allows "domain wide delegation", which seems concerning.
Maybe I'm just not understanding this correctly, but does that mean this service account can now read the contents of all mailboxes in the GSuite account?
How do I make sure this service account is limited to the one mailbox I want it to access?
I think you are talking about user impersonation using the service account. I am afraid that it is not possible to limit the access that the service account can have. The only possible limitations is related to the creations of credentials on the project and things like that, but if a service account has domain wide delegation to do user impersonation, then it is not possible to set up limitations to it.
You can find more info about the possible limitations here https://cloud.google.com/resource-manager/docs/organization-policy/restricting-service-accounts
I have successfully configured qn Azure AD App Registration, allowing a client_credentials based OAuth 2.0 flow to work. This allows a third party application to access Microsoft Graph API. The app has "Calendar.Read" permission. Meaning the app can pretty much read any of the calendars (including CEO's).
I now have a conversation with security. What is out there in the Microsoft world, that I can use to lock down usage of API access via this Application Permission? Is there ability to do things like:
Restrict IP ranges the App can be accessed from?
Restrict users that can access the App? (However in Client_credentials, there is no user context)
Log traffic / activity happening via the App?
The only thing i can think of now is to say the Redirect URL configuration on the app means, no other application can get an access token using the Client_credentials, even if the application id & passkey get compromised
Any advice on further security controls that can be put in place?
Restricting access: You would need to do this in your application. The Client Credential flow doesn't allow for restricting what users as you point out. However there is nothing stopping you from adding user authentication to your application, possibly using a delegated graph auth flow to determine who they are.
IP Ranges: This is not possible currently.
Logging Traffic: This is not possible on the graph side currently, however you could/should log traffic on your applications side.
Redirect urls will not help you because they are not used int eh client credential flow.
In general application only auth (client credential flow) + a broad authorization scope is very powerful, but must be managed correctly. You don't inadvertently want to build a totally new users/permissions model over the top of the graph :)
There are very few options available currently available to offer these controls at token issuance (in Azure AD) or at API access (in Microsoft Graph). However, you can achieve similar results by carefully managing access to the app's credentials. Here are a couple steps you can take (not exhaustive):
App credentials: keep them secret, keep them safe
Use Key Vault. You can configure many of the restrictions you mention for access to data in Key Vault, including IP ranges and which users access. Key Vault also offers auditing of access to secrets. Don't forget to also be careful about which users have management access to the Key Vault (e.g. other users with access to the same Azure subscription).
Use certificates (public/private key pair), rather than client secrets (passwords), to authenticate the app. People tend to manage certificates much more carefully than they manage shared passwords, and developers are much less likely to hard-code the secret into scripts/code.
Be careful and deliberate about which users can manage the app's credentials
This is often overlooked. A user (or another app) who can access existing credentials, or add a new authorized credential to an app can act as the app and (mis)use all the permissions the app has been granted. This includes:
Users (and apps) in the "Company Administrator", "Application Administrator" and "Cloud Application Administrator" directory roles.
Users who are set as owners of the app registration (Application object) and enterprise app (ServicePrincipal object) for the app.
Users (or systems) who have access to the server or service the application resides on (which will have, or have access to, the credentials).
For all of these cases, ensure this is the smallest possible number of users, and they actually have a legitimate need. For users who do need access, wherever possible enforce just-in-time, time-limited access (not persistent access), such as with Azure AD Privileged Identity Management, for time-bound, just-in-time access for Azure AD directory roles and Azure resources.
We have a bit of a dilemma that we are running into with a couple applications that are trying to read a given users email without user interaction to authorize. The key to this approach is that we want no user interaction, and want to load the client server application with the proper JSON credentials downloaded from the Google Developer Console.
I have this approach working for programs where we create a service account in the Developer Console, and then delegate domain wide authority to that account with the proper scope access. However what we are hoping is that we don't have to delegate domain wide authority, and just read the users email who created this developer console project. I have tried many different types of solutions for this, but always run into the same limitation that I have to grant domain wide access.
What I am wondering is if there is any way to gain access to a single users mailbox using a server to server type approach and not have to grant domain wide access?
I appreciate your help with this issue!
There is no supported authorization flow for what you want to do. You must either use a service account that has been delegated domain-wide authority, or you must use a 3LO flow that involves user consent.
It seems you're looking for OAuth for Server to Server Application. You will also be using a service account. But, granting of domain-wide authority for service accounts is an optional thing. You don't have to enable it if you don't want to.
To support server-to-server interactions, first create a service
account for your project in the Developers Console. If you want to
access user data for users in your Google Apps domain, then delegate
domain-wide access to the service account.
Then, your application prepares to make authorized API calls by using
the service account's credentials to request an access token from the
OAuth 2.0 auth server.
Finally, your application can use the access token to call Google
APIs.
I have a google business apps account.
My requirement is to scan all emails of my support email and process them.
This has to be done on the server side without any manual interaction.
I am able to make this work with IMAP, but i am looking at making this work with Google API.
This doesn't work with the Google API unless i do manual client consent.
Or i need to use the service account, in which case i have to get a domain wide access although my requirement is only for one email id. This is against my company's information security policy hence cannot use this option.
Require help on how i can use Google API to do the integration between my server and gmail server at a individual email account level. Any suggestions?