Is it possible to secure a kind with a specific credentials? - google-cloud-datastore

I was wondering if it is possible to secure a kind so that only a user/service-account with a specific credentials can access it.
To give an example I'm thinking to have a kind user, that is going to be used across different envrionments under the same project.
What I was thinkinig of doing is having:
user-dev - used only on dev environment with dev credentials
user-uat - used only on uat environment with uat credentials
user-prod - used only on prod envrioment with prod credentials
If it is not possible what are the alternatives.

Alternative to Sebastien solution is to create a separate projects in google could console for each entity.
A little bit more configuration but gives you a better security model without creating addition layers.
In my example I have created projects:
project_name-dev-storage + entity + service account
project_name-uat-storage + entity + service account
project_name-prod-storage + entity + service account

The alternative would be to save the Entity User under different namespaces. In your case you would then have 3 namespaces:
com.yoursite.dev
com.yoursite.uat
com.yoursite.prod
You then instantiate the Datastore with the corresponding namespace (taken from environment var) according to the environment the application is deployed.

Related

Kusto.Explorer - Authentication Trouble

I'm having trouble adding a connection in the Kusto.Explorer desktop app 1.0.3.949. I can login via Web UI but in the desktop app it gives me this error:
This normally represents a permanent error, and retrying is unlikely to help.
Please provide the following information when contacting the Kusto team # https://aka.ms/kustosupport :
DataSource='https://m1explorer.westus.kusto.windows.net/v1/rest/mgmt',
DatabaseName='NetDefaultDB',
ClientRequestId='KD2RunCommand;5723fa83-9dd5-48fe-a1ee-5d4ddb7f9cd9',
ActivityId='74b41f5e-be7c-46be-88f5-dae1a6d35c30,
Timestamp='2020-08-02T18:48:13.6846740Z'.
In other applications such as the Kuskus VSCode extension or even the Web UI, the problem seems to be that it uses the "common" tenant/authority id as a default. Is there a way to specify the tenant id when adding the connection? It says you can import an .xml file but I'm not sure where or how this can be generated.
Thanks,
Steven
Please try approach described at:
https://learn.microsoft.com/en-us/azure/data-explorer/kusto/tools/kusto-explorer#control-the-user-identity-connecting-to-kustoexplorer
The default security model for new connections is AAD-Federated
security. Authentication is done through the Azure Active Directory
using the default AAD user experience.
If you need finer control over the authentication parameters, you can
expand the "Advanced: Connection Strings" edit box and provide a valid
Kusto connection string value.
For example, users with a presence in multiple AAD tenants sometimes
need to use a particular "projection" of their identities to a
specific AAD tenant. Do this by providing a connection string, such as
the one below (replace words IN CAPITALS with specific values):
Data Source=https://CLUSTER_NAME.kusto.windows.net;Initial Catalog=DATABASE_NAME;AAD Federated Security=True;Authority Id=AAD_TENANT_OF_CLUSTER;User=USER_DOMAIN

Web.Config transforms for Multi-Tenant deployment of WebForms app in docker over AWS ECS

Environment
ASP.NET WebForms app over IIS
Docker container host
AWS ECS hosting platform
Each client hosting its own copy of the app with private database connection string
Background
In the non-docker environment, each copy is a virtual directory under IIS, and thus have their own individual web.config pointing to dedicated databases. The underlying codebase is the same for each client, with no client-specific customization involved. The route becomes / here.
In the docker environment (one container per client), each copy goes over as a central root application.
Challange
Since the root image is going to be the same, how to have the web.config overridden for each client deployment.
We shouldn't create multiple images (one per client) as that will mean having extra deployment jobs and losing out on centralization. The connection strings should ideally be stored in some kind of dictionary storage applicable at ECS level which can provide client-specific values upon loading of corresponding containers.
Presenting the approach we used to solve this issue. Hope it may help others struck in similar cases.
With the problem statement tied to having a single root image and having any customization being applied at runtime, we knew that there needs to be a transformation of web.config at time of loading of the corresponding containers.
The solution was to use a PowerShell script that will read the web.config and get replace the specific values which were having a custom prefix embedded to the key. The values got passed from custom environmental variables within ECS and the web.config also got updated to have the keys with the prefix added.
Now since the docker container can have only a single entry point, a new base image was created which instantiated an IIS server and called a PowerShell script as startup. The called script called this transformation script and then set the ServiceMonitor on the w3cwp.
Thanks a lot for this article https://anthonychu.ca/post/overriding-web-config-settings-environment-variables-containerized-aspnet-apps/
I would use environment variables as the OP suggests for this with a start up transform, however I want to make the point that you do not want sensitive information in ENV variables, like DB passwords, in your ECS task definition.
For that protected information, you should use ECS secrets coupled with Parameter Store in Systems Manager. These values can be stored encrypted in the Parameter Store (using a KMS key) and the ECS Agent will 'inject' them as ENV variables on task startup.
For me, to simplify matters, I simply use secrets for everything although you can choose to only encrypt the sensitive information and leave the others clear.
I dynamically add the secrets for the given application into my task definitions at deploy time by looking up the 'secrets' for the given app by 'namespace' (something that Parameter Store supports). Then, if I need to add a new parameter, I can just add a new secret to the store in the given namespace and re-deploy the app. It will pick up and inject into the task definition any newly defined secrets automatically (or remove ones that have been retired).
Sample ruby code for creating task definition:
params = ssm_client.get_parameters_by_path(path: '/production/my_app/').parameters
secrets = params.map{ |p| { name: p.name.split("/")[-1], value_from: p.arn } }
task_def.container_definitions[0].secrets = secrets
This last transform injects the secrets such that the secret 'name' is the ENV variable name... which ends up looking like this:
"secrets": [
{
"valueFrom": "arn:aws:ssm:us-east-1:578610029524:parameter/production/my_app/DB_HOSTNAME",
"name": "DB_HOSTNAME"
},
{
"valueFrom": "arn:aws:ssm:us-east-1:578610029524:parameter/production/my_app/DB_PASSWORD",
"name": "DB_PASSWORD"
}
You can see there are no values now in the task definition. They are retrieved and injected when ECS starts up your task.
More information:
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specifying-sensitive-data.html

Referencing a Managed Service Identity in ARM-template deploy

When deploying a Microsoft.Web resource with the new MSI feature the principleId GUID for the created user is visible after deployment. Screenshot below shows the structure in the ARM-template.
What would be the best way to fetch this GUID later in the pipeline to be able to assign access rights in (for instance) Data Lake Store?
Is it possible to use any of the existing ARM template functions to do so?
I just struggled with this myself. The solution that worked for me was found deep in the comments here.
Essentially, you create a variable targeting the resource you are creating with the MSI support. Then you can use the variable to fetch the specific tenantId and principalId values. Not ideal, but it works. In my examples, I'm configuring Key Vault permissions for a Function App.
To create the variable, use the syntax below.
"variables": {
"identity_resource_id": "[concat(resourceId('Microsoft.Web/sites', variables('appName')), '/providers/Microsoft.ManagedIdentity/Identities/default')]"
}
To get the actual values for the tenantId and principalId, reference them with the following syntax:
{
"tenantId": "[reference(variables('identity_resource_id'), '2015-08-31-PREVIEW').tenantId]",
"objectId": "[reference(variables('identity_resource_id'), '2015-08-31-PREVIEW').principalId]"
}
Hope this helps anyone who comes along with the same problem!
Here are a few sample templates: https://github.com/rashidqureshi/MSI-Samples that show a) how to grant RBAC access to ARM resources b) how to create access policy for keyvault using the OID of the MSI
There is new way to get identity information. You can directly get them from resource that support Managed Identity for Azure resources (Managed Service Identity in the past).
{
"tenantId": "[reference(resourceId('Microsoft.Web/sites', variables('serviceAppName')),'2019-08-01', 'full').identity.tenantId]",
"objectId": "[reference(resourceId('Microsoft.Web/sites', variables('serviceAppName')),'2019-08-01', 'full').identity.principalId]",
}
You can also get principal Id for resource in other resource group or/and subscription. ResourceId supports optional parameters:
"tenantId": "[reference(resourceId(variables('resourceGroup'), 'Microsoft.Web/sites', variables('serviceAppName')),'2019-08-01', 'full').identity.tenantId]",
or
"tenantId": "[reference(resourceId(variables('subscription'), variables('resourceGroup'), 'Microsoft.Web/sites', variables('serviceAppName')),'2019-08-01', 'full').identity.tenantId]",

Asp.net MVC azure ad group identification

I'm currently finishing my website in ASP.NET MVC with azure AD login.
For this website, some pages are only accessible by admins. For this, I made a new group that's named testAdmins and when I check if the user can access to a page, I use this :
ClaimsPrincipal principal = User as ClaimsPrincipal;
if (principal.Claims.Any(x => x.Type == "groups" && x.Value == "id of testAdmins")){ //code }
And it's working fine with my user witch is in this group.
But when I change the id of testAdmins with the value of the real group of admins (Admins) I'm going to use when the site will be deployed and witch I'm not in, the server is not showing anything for 40 sec and then I got this message :
An exception of type 'System.Web.HttpException' occurred in
System.Web.dll but was not handled in user code
Additional information: Unable to connect to SQL Server database.
Can someone explain me what's going on ?
Thanks in advance
PS : I made some more test... When my user is in the group it works fast but when it's not it takes 2 min and do the error message... if someone as no idea what is the problem, did anyone have a way to make different access from user wich are in a special group from Azure Active Directory ?
Provide the whole stacktrace and relevant source code line (the full stacktrace includes file names and line numbers!). The issue you are facing is very common for on-boarding developers (on-boarding to ASP.NET 4.0+).
Your project is based on the default project template for ASP.NET 4.0 (or later), which by default creates the website with "Local User Accounts". This template creates an Entity Framework db context and local models for the user authentication / authorization. This also creates some settings in your web.config to define connectin strings (or instruct the default one) for the EF.
On top of that template you added the neccessery Azure AD authentication details - either through the right click menu (Configure Azure AD Authentication - available in VS 2015) or manually by including a bunch of NuGet packages. Thus you (without knowing) created a nasty mix of FBA (Forms Based Authentication) - dictated by the local accounts, and OpenID Connect - dictated by Azure AD authentication.
The SQL Server error comes from that FBA (or local user accounts setting) config. And there is no easy way to remove it.
Because I see you are just playing around and testing out things, I would warmly recommend that you start over with a new project and be careful by your second step of the wizard (available in both VS 2013 and VS 2015) - Click on "change authentication" and chose "No authentication":
On this clean project, you can add your Azure AD authentication and everything will work and you will not see any SQL Server Errors (well it depends how you configure your Azure AD Auth - some of the wizzards - namely the one of Multi-tenant also creates EF context).

Multiple applications in the same Symfony2 application

This is quite a long question, but there's quite a lot to it.
It feels like it should be a reasonably common use case, so I'm hoping the Stack Overflow community can provide me with a 'best practice in Symfony2' answer.
The solution I describe below works, but there are several consequences I'd like to avoid:
In my local dev environment, if I have used the wrong db connection the test will work in dev but fail on production
The routes of the ADMIN API are accessible on the PUBLIC API url, just denied.
If I have a mirror of live in my dev environment (3 separate checkouts with the corresponding parameters.yml file) then the feature tests for the other bundles fail
Is there a 'best practice in Symfony2' way to set up my project?
We're running a LAMP stack. We use git/(Atlassian) stash for version control.
We're using doctrine for the ORM and FOS-REST with OAuth plus symfony firewalls to authenticate and authorise the users.
We're committed to use Symfony2, so I am trying to find a 'best practice' solution:
I have a project with 3 applications:
A public-facing API (which gives read-only access to the data)
A protected API (which provides admin functionality)
A set of batch processes (to e.g. import data and monitor data quality)
Each application uses a set of shared models.
I have created 4 bundles, one each for the application and a 4th for the shared models.
Each application must use a different database user to access the database.
There's only one database.
There's several tables, one is called 'prices'
The admin API only must be accessible from one hostname (e.g. admin-api.server1)
The public API only must be accessible from a different hostname (e.g. public-api.server2)
Each application is hosted on a different server
In parameters.yml in my dev environment I have this
// parameters.yml
api_public_db_user: user1
api_public_db_pass: pass1
api_admin_db_user: user2
api_admin_db_pass: pass2
batch_db_user: user3
batch_db_pass: pass3
In config.yml I have this:
// config.yml
doctrine:
dbal:
connections:
api_public:
user: "%api_public_db_user%"
password: "%api_public_db_pass%"
api_admin:
user: "%api_admin_db_user%"
password: "%api_admin_db_pass%"
batch:
user: "%batch_db_user%"
password: "%batch_db_pass%"
In my code I can do this (I believe this can be done from the service container too, but I haven't got that far yet)
$entityManager = $this->getContainer()->get('doctrine')->getManager('api_public');
$entityRepository = $this->getContainer()->get('doctrine')->getRepository('CommonBundle:Price', api_admin');
When I deploy my code to each of the live servers, I put junk values in the parameters.yml for the other applications
// parameters.yml on the public api server
api_public_db_user: user1
api_public_db_pass: pass1
api_admin_db_user: **JUNK**
api_admin_db_pass: **JUNK**
batch_db_user: **JUNK**
batch_db_pass: **JUNK**
I have locked down my application so that the database isn't accessible (and thus the other API features don't work)
I have also set up Symfony firewall security so that the different routes require different permissions
There's also security in the apache vhost to deny access to say the admin api path from the public api directory.
So, I have secured my application and met the requirement of the security audit, but the dev process isn't ideal and something feels wrong.
As background:
We have previously looked at splitting it up into different applications within the same project (like this Symfony2 multiple applications and api centric application. Actually followed this method http://jolicode.com/blog/multiple-applications-with-symfony2) , but ran into difficulties, and in any case, Fabien says not to (https://groups.google.com/forum/#!topic/symfony-devs/yneojUuFiqw). That this existed in Symfony1 and was removed in Symfony2 is enough of an argument for me.
We have previously gone down the route of splitting up each bundle and importing it using composer, but this caused too many development overheads (for example, having to modify many repositories to implement a feature; it not being possible to see all of the changes for a feature in a single pull request).
We are receiving an ever growing number of requests to create APIs, and we're similarly worried about putting each application in its own repository.
So, putting each of the three applications in a separate Symfony project / git repository is something we want to avoid too.

Resources