How to Override Identity Management module for Multi-Tenancy - abp

I was wondering how to Override the Identity Management Module to Work with Multi-tenant Web-Apps in Abp Framework . I want to Make my newly registered Users to become the admin of their own tenant and be able to Manage (Crud + Permission / Role Management ) their Subset users? For now I've created a custom UI to manage them, but I'm curios if it's possible to configure the Identity Management Module to do the job?

Ok looks like I just need to create an "Admin" role and make it my default role for each tennet
https://github.com/abpframework/abp/issues/10995

Related

Automate AWS RDS User Management

Most of you would have encountered the problem of creating db users for developers across multiple database (using common user is not allowed). We have around 90 DB's on AWS and 200-250 dev's. Everyday someone needs access to a database and this is manual and repetitive task.
I am looking for a solution to automate end-to-end lifecycle of user management, scripting or creating a terraform module are solutions which I already have in my mind, but how does other organization manage DB users at scale ?
I did look at AWS IAM authentication but I am not sure how can we grant fine grain access using IAM roles.
Cheers,
Fun Learn
The way I've done this is (high level);
Create your RDS Terraform Config / Module(s)
Create a sql file with the user & grant creations needed
Create a wrapper script that deploys terraform then connects to it to deploy your SQL file with user creation
Your wrapper script will need to use Terraform Outputs to get your newly created RDS Endpoint to connect to | Say you created an output called rds_endpoint in your terraform plan / config... This is how you grab it in bash terraform output rds_endpoint
Assuming your new RDS DB is not publicly accessible, your wrapper script will need to tunnel in through a bastion or some other instance that is publicly accessible with access to the DB. Example: ssh -oStrictHostKeyChecking=no -p 22 -i ~/.ssh/bastion-host-key.pem -C -N ec2-user#$bastion_ip -L 3306:$rds_endpoint:3306 &
Your wrapper script will need to use the RDS user & password you created with terraform as well to run the SQL File
In fact IAM authentication could be the key to do that.
What you can do is in fact create all you databases with terraform.
do not forget to enable iam authentication via your terraform module.
Once all you databases are created via teraform, you have to create local role(s) in all of theses databases (either via terraform using SQL script or still via terraform using modules that allow you to create user/roles, for postgresql you can use this module ) and you have to grant them the pre-created, existing, database role for iam (for example with postgresql its named "rds_iam")
The thing that is interresting with iam authentication is that all of your developper can connect using their account to aws and request a token that will be used as a password (the username will be the role you created before) and by doing this you create only one role, but each authentication is made by each developpers account.
If your company really needs you to create roles for each devs (even if the roles are exactly the same, It makes no sense since by definition, we ASSUME a role, so anyone can assume ONE role, this is not awful) you can then create a local database users (instead of a role) for all of your developpers in all of your database by using an SQL script that your terraform will execute.
Of course do not forget to grant the rds_iam existing role to either the unique role that will be used by all the developpers (in case you choose this solution) or to all the db users you created before.
You will have to manage IAM policy for all of theses users to be accurate regarding to the security (or use * in the policy to let all your developpers connect to all you db users lol)
and then your developpers will be able to use aws rds command to generate an auth token and connect to their local db user that will have to correct rights.
There is a hole bunch of informations and precisions here:
https://aws.amazon.com/premiumsupport/knowledge-center/users-connect-rds-iam
have a nice journey on aws

Add user properties to Azure Active Directory for SCIM provisioning (HiBob)

I'm trying to setup a user lifecycle flow that will allow me to create an Azure Active Directory user (Member, not Guest) when an employee is created in our HRIS tool (HiBob). There is a pre-existing integration which is enabled and allows us to get basic information (name, location, etc.).
In the HRIS system we also store some more unique data that I would like to be added to the users AAD profile (maybe an emergency contact for example) that we can then use to provision other applications (like Slack).
My issue is trying to create these custom property fields. I have read about Azure B2C as well as directory schema, custom security extensions and using MS Graph. None of these seem to be totally relevant to my situation.
FYI we are fully cloud, so Azure AD Connect is also not an option.
To store custom data in Azure AD objects such as users you can leverage Azure AD Directory Extensions in tandem with Azure AD Provisioning trough SCIM.

What are good practices for granting database permissions to a web service connection?

I have been searching for articles and SQL script examples that would demonstrate how to securely and conveniently solve one of the most common scenarios - connecting from a .Net Core Entity Framework based web application to an SQL database.
But somehow I could not find any coherent step-by-step guide from a reputable source.
Let's assume the following:
I cannot use integrated Windows auth in the connection string and must use username and password based auth (because hosting on a Linux server and the DB is on a different Windows server)
the web service will need your usual minimum set of permissions - connect to the database, read data, write data, delete data, execute stored procedures
While reading many tutorials, I find there are multiple ways to manage the connection permissions. To avoid this question being too broad, I'll list my current choices as I understand them (please correct me if I'm missing something).
Users and logins:
create a login and a user for the database
create a database-only user without a login (not sure if this is applicable to a web app and connection string, but still it's a feature that I've seen being used)
Assigning permissions:
assign the user to some fixed SQL role (db_datareader, db_datawriter AND also will have to grant EXECUTE permission)
grant all fixed permissions
create a custom role (let's say, db_web_apps) with required permissions
Which choices are better (more secure and easier to manage in general) and recommended by SQL DBAs?
I think every database administrator should have a template script handy for quickly adding a new user with minimum required permissions every time when developers ask for a new connection for their shiny new web app.
If you know a good, reliable tutorial or GitHub / Gist example that explains what and why is being done that way or a script that you yourself have used for years without any issues in production environments, I'll really appreciate if you could share it.
Create a role in the database and assign the required privileges to the role. Don't use the fixed database roles. Instead grant permissions directly to objects, schemas, or the entire database if necessary. Like this:
create role trusted_app_role
grant select, insert, update, delete, execute
on schema::dbo to trusted_app_role
That will grant the role full DML permissions on all the objects in the default dbo schema. So if you have any tables or procedures you don't want the app to have access to, just create them in a different schema, say, admin. This way you never have to fiddle with permissions as you add objects. The fixed database roles predate schema-based permissions, and aren't really needed any more.
For your application's identity, add Active Directory or Azure Active Directory (Azure SQL) identities to this role, or, if you can't, add SQL Users to the role.
If you are on Azure SQL, you should normally use a database user without a login. On SQL Server you can only add "contained database users" if you enable Partial Database Containment. Which you can do, but is incompatible with Change Tracking and Change Data Capture, so it's a tradeoff.
So normally for SQL Server you still create a login and map the user to the login. EG:
create login web_service_user with password = '5X+jeuAB6kmhw85R/AxAg'
create user web_service_user for login web_service_user
And then add that user to your role
alter role trusted_app_role add member web_service_user

Difference between "System Assigned" Identity and App Registration "Service Principal"

Can someone help me understand the difference between the Service Principal created when I create an App Registration in AAD and the Managed Identity that gets created when I enable "System Assigned" on the Identity blade of an App Service?
We have an App Service that we are developing that we have created an App Registration for and we have also enabled the System Assigned identity. When we go into Enterprise Applications under AAD and search for our app, it comes up with 2 entries. One for the Managed Identity and one for the Service Principal created as part of the App Registration. We are trying to understand which one we would use to give the app permissions to write to an Azure SQL DB.
Managed Identities are essentially service principals wrapped with Microsoft logic to make accessing resources simpler. Although, sometimes adding more layers may complicate things, the idea is to make it easier, simpler, and less consumer interactive.
For your scenario, you'll want to think about what you would like to do. Would you like to have more control and implement your own logic with an Azure SQL DB protected by AAD, or try utilizing Microsoft's Managed Identity to protect/access the Azure SQL DB resource. (Ideally the Managed Identity path should be less work)
The tutorial for using Managed Identities to access an azure SQL db from an app service can be found here :
https://learn.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-connect-msi
The docs for protecting an Azure SQL DB using Azure AD can be found here :
https://learn.microsoft.com/en-us/azure/sql-database/sql-database-aad-authentication
Furthermore Managed Identities are explained in the official Microsoft documentation here :
https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview
It's important to note that there are two kinds of Managed Identities.
From the documentation:
A system-assigned managed identity is enabled directly on an Azure
service instance. When the identity is enabled, Azure creates an
identity for the instance in the Azure AD tenant that's trusted by the
subscription of the instance. After the identity is created, the
credentials are provisioned onto the instance. The lifecycle of a
system-assigned identity is directly tied to the Azure service
instance that it's enabled on. If the instance is deleted, Azure
automatically cleans up the credentials and the identity in Azure AD.
A user-assigned managed identity is created as a standalone Azure
resource. Through a create process, Azure creates an identity in the
Azure AD tenant that's trusted by the subscription in use. After the
identity is created, the identity can be assigned to one or more Azure
service instances. The lifecycle of a user-assigned identity is
managed separately from the lifecycle of the Azure service instances
to which it's assigned.
The picture from the official docs also gives a good example of a VM using MSI(Managed Service Identity).
This is Provided below:
In addition to that, the App Service Managed Identity documentation can be found here :
https://learn.microsoft.com/en-us/azure/app-service/overview-managed-identity
I would like to elaborate a little further as the topic around service principals and app registrations in Azure can be confusing.
As you noticed, a service principal will get created in your AAD tenant when you turn on system-assigned managed identity for a resource in Azure. This service principal is tied to the lifecycle of your resource or in other words: If you delete your App Service, Azure will delete the service principal for you [2].
Beside service principals, there are other object types that live inside a tenant: User principals and application objects. As the name suggests, user principals identify a user while a service principal can be used to either identify a resource in Azure or an application object. To both types of principals you can assign roles, as you mentioned you can create a new user in your database and use the system-assigned identity (Service Principal 1 in the image below) to let Azure SQL know that your App Service has permissions to access the database [3]. This is marked in red in the image.
When you create an app registration, two objects are created: An application object and a service principal in your tenant (this is "Service Principal 2") [4]. You could now use this service principal as well to give it permissions to access the database (marked in orange in the image) but this service principal is not tied to your Azure App Service and doesn't represent it. In other words, if you want to use Service Principal 2 in your App Service, beside creating a user for this service principal in your database you'd additionally also need to get an access token for this service principal whenever you create a new SQL connection to the database in your application. It's possible but a bit more inconvenient and the beauty of using system-assigned identities is that your App Service knows about its service principal already and you don't have to manage it on your own (e.g., delete it when your App Service gets deleted).
Long story short: Use the system-assigned managed identity in your use case.
[2] https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview#managed-identity-types
[3] https://learn.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-connect-msi#grant-permissions-to-managed-identity
[4] https://learn.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals
You can only use the managed identity that you have enabled in your App Service for authentication to AAD which eventually allows you to access your Azure SQL instance based on roles/permissions. I'd tried using the service principal/Enterprise Application created as part of App Registration process for authentication and it didn't work.
The way I see it is that the App Service is what runs/hosts your application and only this managed identity/SP is available to your running application for authentication to AAD.
The Service principal/Enterprise Application is being used internally for some other purpose and, it is not available to our application for authentication to AAD.
Just a wee note. App Registration may live without Service Principal. App Registration may represent an application that is consumed, not necessarily the consumer.
Managed Identity is solely a client-based identity.
E.g. Your App Service is acting as a client, when accessing Azure SQL. In this case you don't need an app registration and its service principal at all. You will only need a Managed Identity (which is a Service Principal).
When your App Service (A) is opposed to access another App Service (B) then again your App Service (A) does not need an app registration. But App Service B needs to have an app registration.
Imo when you want to use the credential-less approach in Azure, an app registration is acting as the server part and a Managed Identity (system - or user-assigned) is considered to be the client part.

How to persist Identity Server consent in a database?

I'm attempting to develop a .NET Core Identity Server but I can't seem to figure out where to hook in to persist consents in a database. My understanding is that when the use consents to the scopes of an application and checks the Remember Consent checkbox that in only stored in memory by default and if the Identity Server were to restart, the user would have to consent again. Is there a way to persist consent in something like a database so it can be remembered beyond a service restart?
you can use something like Entity framework to persist data in the database,
here is the docs for how to configure EF with Identity Server.

Resources