What is the best way to manage domain specific services? For eg: In a Financial domain, Should I have a global service "AccountCreation" or "CheckingAccountCreation", "CreditcardAccountreation" etc.
I am struggling whether to keep them at global level or keep them at the product level. what is the best approach?
You should probably focus in the data first: what data is there, and what data needs to stay consistent. Then focus on what the behaviours around that data are.
In a Financial domain, Should I have a global service "AccountCreation" or "CheckingAccountCreation", "CreditcardAccountreation" etc.
In this example, I would say that you have an "account" service, because you clearly have some accounts - and you probably have to ensure that, eg, you don't duplicate account numbers, apply anti-fraud rules, manage the workflow of creation, etc.
Your examples identify some behaviours: create a checking account, create a credit card account. Those would appropriately be commands that you send to the service, because they result in mutation of the data that the service owns.
If you add a "customer" service, though, that would be distinct from the accounts service: it doesn't have to be consistent with the account service, just to have a reference from accounts to customers by ID.
You also generally don't have shared behaviour that touches both parts - updating data about a customer shouldn't touch the details of their accounts (directly), and updating an account doesn't change the details of a customer.
You might have business rules in one service that change another, such as the account service listening for "a customer became a student" announced by the customer service, and then doing some internal processing.
Related
In some B2B applications that employ multi-tenancy, a single user can belong to multiple tenants. Slack, for example, allows the same user (email+password combination) to view all the workspaces (tenants) they belong to and alternate between them seamlessly. As users switch workspaces, the application switches context to the selected workspace, loading workspace-specific entities such as channels, messages, and threads.
Is it possible to do something similar with Google Identity Platform (GIP)?
I understand that in multi-tenancy in GIP, all users are scoped to zero or one tenants. If a person needs to belong to 2 tenants, 2 users must be created - each with their unique uid. This is not a big deal when users sign up with Federated Identity Providers. They see a consent screen twice, confirm, and the application can apply some logic to know they are the same person. For example, it can hash their email address, and link the two tenants to it.
But if users log in with email+password, such approach requires users to maintain two passwords for the same service, diminishing the user experience.
I imagine that one solution is to disable multi-tenancy and store the user-to-tenant links in Firestore, or perhaps as a custom claim so that Firestore Security Rules checks don't require an extra read on every request. However, this might make it harder to enforce different authentication requirements for different tenants. For example, a user may switch context to a tenant that requires 2FA as part of their policy, and it could be advantageous to have GIP manage that part.
Are there better approaches for such a scenario?
I am experimenting with Hash Time-Lock Contracts in Corda, using the Corda account-based model. It seems to me that, to transact with an account, you must always obtain an Anonymous Party to serve as its public key, via subflow RequestKeyForAccount. And it seems that you will always obtain a different key each time you RequestKeyForAccount, even for the same account.
Assuming the above statements are correct, I am finding it impossible to implement the contract, as the contract must be able to identify whether the public key invoking it belongs to the "locker" or the "lockee" party. The Anonymous Party will always be different, and will never match either the "locker" or the "lockee," because it will be different every time I invoke RequestKeyForAccount.
I have also tried tackling the problem in a different way, by storing "locker" account and "lockee" account in my persisted state - but, the contract does not have access to the account that is invoking it. It has access to the signers - which are AbstractParties. The account invoking the transaction does not seem obtainable.
Bottom line, I cannot implement a contract that tries to ascertain whether the account invoking it matches a particular account stored within the associated state, due to the random anonymized values returned by RequestKeyForAccount; and due to the inaccessibility of account when all I can access are the signers of the transaction, i.e. AbstractParties. I'd appreciate if somebody can tell me if I am off-base in any of my statements.
Always remember that Accounts in Corda are only logical entities. They do not sign transactions and they do not invoke flows in the cordapp. It's their hosting node that does it on behalf of the accounts they own.
So, as also stated in training.corda.net, if you want to restrict access to certain states to a particular account, you have to manage it outside of Corda (for example, create a RPC user that is linked to an account at application level, with the needed restrictions):
Data access restrictions, i.e. restricting users (i.e. Corda accounts) to interact only with states that they own, is the CorDapp developer's responsibility as implementing them is outside of Corda’s scope.
I am a newbie to firebase and need some suggestions on structuring data.
I am designing a database for an application where multiple people may share a bank account and can update the status of this account. The group of people sharing this account may also keep changing. So, multiple people may perform actions which will influence the balance available in an account. I decided to list the linked accounts under each user so that one pull is enough to get a list of all user accounts once user logs in. If user is interested in details of a specific account (like balance) then I will go and fetch that child from accounts sub-tree. It all seems fine until I think about notifying users in a smartphone app if the balance associated with any of their linked account changes. Since the balance attribute is not under any specific "user" sub-tree, how to monitor for this change at the application level.
I don't want to bring balance attribute under "user" sub-tree or else I will have to find the duplicate copies and update all of them whenever balance of an account changes. Moreover this approach will not scale well.
Any suggestion?
The ability to add, update, and delete various entities in my application is often determined by the relationships defined between the various users involved. Here is an example:
A basic user or his supervisor can create tasks associated to the user, but only his supervisor can lock down the task so that the basic user will not longer be able to add/update/delete it. Until locked down, both individuals will be able to update the task.
What is the best approach to implement these kind of complex and advanced rules that deal with the relationship of users and the state of the entities (new, existing), as well as other things like maybe a user-defined status associated to the entity?
Thanks
What is the best approach to implement these kind of complex and advanced rules that deal with the relationship of users and the state of the entities (new, existing), as well as other things like maybe a user-defined status associated to the entity?
You want to use an authorization standard, namely XACML, the eXtensible Access Control Markup Language. XACML is:
a standard developed by OASIS, just like SAML is
a standard that focuses on fine-grained access control: access control that takes into account user information, resource information, state, and contextual information
a standard that implements the attribute-based access control (ABAC) model: the user information, resource data, and state can all be seen as attributes
a standard that uses policies and rules to structure the attributes and grant / deny access: XACML is policy-based
a standard that can be applied across multiple layers e.g. across the presntation tier, the data tier, the business tier of an MVC application
a standard that can be applied to multiple technologies and languages e.g. C# (MVC4 and more), Java, Python...
With XACML, you can easily implement relationships e.g.: an employee can approve a transaction if and only if the transaction amount < employee approval limit AND the transaction is not locked.
Where to go from here?
Check out NIST's page on ABAC.
Check out OASIS XACML's page and spec
Check out existing implementations (open-source and vendor such as the one I work for, Axiomatics.)
At a bank I worked for, we had a loan management system that allowed the entire bank hierarchy to see loans in their reporting structure. For instance, a Market exec could see the loan portfolio of all of his/her reports at once. Additionally, s/he had the ability to select from a list of all reports' (direct or indirect) names to view the portfolio of that employee.
It was complex, but we had to maintain an HR database of the reporting structure. Once we had that, we built user functions (could be done as stored procs, too, but user functions worked well in our LINQ to SQL backend) that allowed us to check whether user x supervises user y.
So, in your example, as long as you know who owns the task, and have access to a method that can be used to determine if the task owner reports to the currently-logged-in user, you should be able to easily enable/disable the "lock" button on the page.
The legwork lies in creating that reporting structure DB, and keeping it up to date!
My company is building an ASP.NET HR application and we have decided to create one database per client. This ensures that clients cannot accidentally view another client's data, while also allowing for easy scalability (among other benefits, already discussed here).
My question is - what is the best way to handle security and data access in such a scenario? My intent is to use a common login/account database that will direct the user to the correct server/database. This common database would also contain the application features that each user/role has access.
I was not planning to put any user information in each individual client database, but others on my team feel that the lack of security on each database is a huge hole (but they cannot articulate how duplicating the common access logic would be useful).
Am I missing something? Should we add an extra layer of security/authentication at the client database level?
Update:
One of the reasons my team felt dual user management was necessary is due to access control. All users have a default role (e.g. Admin, Minimal Access, Power User, etc.), but client admins will be able to refine permissions for users with access to their database. To me it still seems feasible for this to be in a central database, but my team doesn't agree. Thoughts?
We have a SaaS solution that uses the one DB per client model. We have a common "Security" database too. However, we store all user information in the individual client databases.
When the user logs into the system they tell us three pieces of information, username, password and client-id. The client-id is used to lookup their home database in the "security" database, and then the code connects to their home database to check their username/password. This way a client is totally self-contained within their database. Of course you need some piece of information beyond username to determine their home database. Could be our client-id approach, or could be the domain-name requested if you're using the sub-domain per client approach.
The advantage here is that you can move "client" databases around w/out having to keep them synced up with the security database. Plus you don't need to deal w/cross-db joins when you're trying to lookup user information.
Update: In response to your update... One of the advantages to each customer having their own DB is also the ability to restore a customer if they really need it. If you've split the customer's data into two databases how do you restore it? Also, again, you'll need to worry about cross-db data access if the users are defined in a DB other than the home DB.
I've always been of the opinion that security should be enforced at the application level, not the database level. With that said, I see no problem with your intended approach. Managing accounts and roles through a central database makes the application more maintainable in the long run.
You may want to look into using the ASP.NET membership provider for handling the authentication plumbing. That would work with your stated approach and you can still keep all of the authentication data in a separate database. However, I agree with Chris that keeping one DB will utlimately be more maintainable.