|
D4rkTrick wrote: "in which roughness should I store permissions?"
Having considered that many times what I came up with is that you cannot answer that question without business requirements. And probably some business domain knowledge yourself.
Consider these cases...
Who should have permission to edit a social security number at a company? Who should be able to view it?
Contrast that with who should have permission to change the delivery address? Who should be able to view it? (Even more prickly can someone change a delivery address on an order that has already been delivered?)
Should there be a admin (root admin) that can change everything?
Are there assets that will be shared between companies? If so then who sets the permissions? (That was a very real business case that I had to deal with.)
Answering questions like that is FAR more important than how you implement it in general. But it will certainly drive implementation details.
I would be very wary of suggestions that you should 'plan for the future'. For instance in one of many parallel futures you might be asked to add a field on one form, so obviously the solution is that every single field on every form must have a permission from the beginning. And then the users (not developers) who will be actually setting that up will need to understand hundreds of permissions and implications (like what if the social security number is on two different forms?)
I worked for a company with hundreds of permissions. No one knew what they all did. There was also disagreement about what they should do. So those tasked with changing them just had to experiment.
D4rkTrick wrote: "should I use RBAC, UBAC, ACL,... and how would I concretely implement them, cleanly?"
I doubt 'cleanly' exists in any medium size application. And really unlikely when it gets bigger.
So just pick one and look at it in detail.
And then really study how to log changes that users make. All users. Log in this case means to a persistent data store. Adds and updates are easy. Deletes are much harder.
|
|
|
|
|
I didn't mean to try to find the answers here on the board, sorry for the misunderstanding. The questions were merely examples. I'm aware that "clean" or "good" are adjectives that are strongly coupled to the use case.
My main goal is to find good literature.
|
|
|
|
|
I understood that.
I was merely pointing out that there is no general answer. Rather you need to start with the domain space rather than than trying to find one solution.
If you don't have an actual domain space, or perhaps even if you do, then just pick one of the solutions and study it.
|
|
|
|
|
Can't tell if you want to secure a door or an app.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
App
|
|
|
|
|
|
Thank you. The information seems quite specific. Do you also have literature for a more abstract - close to mathematical - level?
|
|
|
|
|
It's a "Pattern"; like doors and windows. An abstraction of a "door" or a "window"? That would be a rectangle; with a hole. Math? Width and height.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
Here's the literature I was able to find through libera on IRC. Very helpful to me. Hopefully also helpful for other people reading this..
Online:
Books
In regard of books I found that looking at the references can help. In combination with archive.org's free book library it's possible to skim over books quite quickly
Specific topics
Object Capability System:
Quote: the object graph is the permission graph, and so there are no separate access control checks that you have to make like shown in that slide. An object has authority to call methods on another object if and only if it actually has a reference to that other object.
Links:
- Habitat Chronicles: What Are Capabilities?
- http://erights.org/talks/thesis/markm-thesis.pdf
- Bringing Object-orientation to Security Programming (Mark S. Miller, Google) - YouTube
OT
Here's some basic insight I've gained during looking at various sources.
The basic question you want to get answered is has_access(user, action, resource) . Example: has_access(uid, read, user_list) . You might want to take it even more abstract and say has_access(entity, action, resource) , where entity could be a user, a group, an organization or anything else that is able to perform actions in your system. Perhaps even has_access(resource, action, resource) might be an appropriate abstraction.
With a hierarchical permission structure, you would need a recursive check function:
r = resource
loop:
if(r.has_access(user, action)) return true
r = r.parent()
if( r == null) return false
If a resource can be owned by several parents, you would need to account for that with r.parents() .
|
|
|
|
|
I use IODA architecture since the very beginning, nearly 10 years now. I develop SW more than 30 years as a profi.
It is the first approach/technique, that offers the option to produce reusable, small classes like "lego building blocks".
It is ortogonal to other best practices like CleanCode, DRY and other.
It has a strong impact on unit testing: Unit testing will be easy.
The reason is simple:
IODA was designed to reduce dependencies between classes to a minimum.
I - Integration - calls all other, but does not contain logic or data
O - Operation - contains logic, just work with data, do not know other operations or integrations
D - Data - holds the data and knows/deals only about itself and its childs. No operations here.
A - API - Application Interfaces - To deal with the environment or to provide general functions like data validation and other stuff
All of these classes are devolped by the project. Standard-Libraries can be found below this code.
If you then divide the Operations in "IO operations" and "other operations" you get the following:
IO_operation "reader" reads "data_ger",
operation "translator" translates "data_ger" to english data "data_eng"
and then the IO operation "View_data" presents it to the user.
And the integrator "TextManager" has a method like
void viewAsEnglish(int textIdGer, string readLang = "ger")
{
var data_ger = reader.Read(textIdGer, readLang);
var data_eng = translator.Translate(data_ger, "eng");
dataViewer.View(data_eng);
}
After longer practice you will automatically think in these four types, when creating a new class.
And yes, it will work fine in real projects.
Now lets start discussion about it, if you want.
**Links**
Detailed description:
https://www.infoq.com/news/2015/05/ioda-architecture/[^]
Bigger sample project (documentation only in german, sorry)
GitHub - jpr65/VersandEtiketten: This is a reference projekt for IODA and also a developer test ticket. Only in german, possible later also in english.[^]
** Images **
IODA - Principle Diagram
IODA - Libraries
modified 1-Dec-23 2:53am.
|
|
|
|
|
I haven't seen this architecture before. Seems interesting but there is one thing I don't get:
Ralf Peine 2023 wrote: I - Integration - calls all other, but does not contain logic or data
O - Operation - contains logic, just work with data, do not know other operations or integrations If I need to to implement something like "if operation1 fails do operation2", where do I place the logic? I cannot place it in the integration units (cannot contain logic or data) and cannot place it in one of the operations (do not know other operations).
What is the solution?
Mircea
|
|
|
|
|
Yes, that's some important point.
You may add minimal logic into the integrator to set switches for the workflow.
However, the decision why a switch is set should again be made in an operation, if it is not a simple true/false decision.
It is ***allowed*** to put logik in integrators, sometimes it is easy for the moment, but this leads to technical debt and is sometimes difficult to test. Especially while doing hotfixes, you will break the IODA principles, and this is ok, for the moment.
The more you stick to the IODA principles, the more testable and reusable the code will be, that you create.
|
|
|
|
|
Like perhaps everything along these lines it has some utility as long as it is not taken as an absolute.
I certainly do not want to see every single operation in a million line application decomposed like this.
For example I have written reports at various times in various languages and attempting to decompose them often lead to nothing but making it harder to understand the whole.
Then after that one must consider in standard business programming of maintaining an application over years with multiple changes in employees is this likely to be rigorously maintained? If it isn't then doesn't it just devolve into what the original code might have looked like the first place?
|
|
|
|
|
I see ETL: extract, translate, load.
Your sample "integrator" looks more like a "translator".
While my "data" may not have methods, it resides in a repository that does: add, delete, update, query. Data as another object. The methods represent an "API".
And I have "operations" that depend on other operations: "distance" calculators for anything that needs to calculate a distance (in pixels, paces, yards, or feet); or an angle; or "a collision detector" while moving.
I don't disagree with the architecture, but things aren't that clear cut.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
This example and the dokumentation are very small. Please read the detailed description of Ralf Westphal.
"Translation" is what the integrator manages, and "integration" is the type of the class in the meaning of IODA.
Reason for IODA approach is the following
"Functional dependencies are evil!"
Only the integrator classes are allowed to call operation classes.
So, in an ideal world, you have no functional dependencies.
|
|
|
|
|
If you want people to appreciate the benefits of this approach, write an article, hosted here on Code Project showing a non-trivial application created using these techniques. I find myself deeply distrustful of prescriptive ways of working when they are presented as absolutes (e.g. "Functional dependencies are evil!"). No approach is 100% perfect and, generally, there are always be exceptions to the absolutes that are the driving reason for a new way of working.
|
|
|
|
|
I'm working on a WPF app for a client that gets invoice remittance data from their customers as CSV files. My app extracts the Invoice Date, Reference Number, and Amount using metadata defined by my client for the input files. This metadata defines the columns in the file, and the index position of the Invoice Date, Reference Number, and Amount.
The key is the reference number. It is used to look up the invoice row in their accounting system. Once in a while their customer formats the reference number wrong. For example, one of the reference number formats is eight numbers, as in '20158011'. But from time to time, they send invalid data, as in 'RECOUP19718470_002ZT'.
Another customer's format is 'RDHC608965'. This column's reference number always starts with 'RDHC'. The remainder is the six-digit reference number.
What I would like to do is provide a place in the UI to define the required format of the reference number. If it was internal I would specify a regex, but this is something that my client has to define.
What's the right way to go about this?
In theory, theory and practice are the same. But in practice, they never are.”
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
|
|
|
|
|
"Reference data" is just that; there's nothing to validate. It's like a "comment"; subject to the whims of the client and not something to build a "system" around.
"Invoice payments" are generally applied to outstanding balances, and not any particular invoice; that shows how "important" the reference number is (not).
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
modified 15-Nov-23 20:27pm.
|
|
|
|
|
Gerry Schmitz wrote: "Reference data" is just that; there's nothing to validate. It's like a "comment"; subject to the whims of the client and not something to build a "system" around.
It's not 'Reference data'. It's a Reference Number. The Reference number in the customer's data file is a 'reference' to an Id in the client's accounting system. This matches an invoice from the client to a customer's payment. It's a reconciliation.
But that's not the question. See this[^]
Since my client can define new customers in the app, I need a way for them to tell me the FORMAT of the Reference Number. Then, my app is reading the file, I can verify the number so it can be looked up. The format of the Reference Number CAN be validated. I COULD use a RegEx, but defining the validation for it has to be user friendly.
The question, again, is how to allow the user some way of manually inputting the format of the reference number.
In theory, theory and practice are the same. But in practice, they never are.”
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
|
|
|
|
|
It's reference "junk" when it's in some one else's system that you have no control over. And anything you put in the way of "the payment process" makes you the problem.
A company issues their own "client numbers", Purchase Order numbers, Invoice Numbers, Product Numbers, etc. which becomes "reference junk" in someone else's system that they then send back to you as more "reference junk". You reconcile your own paperwork; not someone else's.
I'd send "checklists" of the outstanding invoices if they wanted to "reference" something.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
This whole process is outside of this discussion. I have no control over how my client processes their invoices.
Thank anyhow
In theory, theory and practice are the same. But in practice, they never are.”
If it's not broken, fix it until it is.
Everything makes sense in someone's mind.
|
|
|
|
|
You have (some) control when inputing from documents; then you can use "fuzzy" searching then and there.
You said CSV ... which means, you have to get it into the system "before" you can do anything with it. Throughput.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
Kevin Marois wrote: What's the right way to go about this?
Your requirements description is incomplete for a start.
You must also answer the question - what do they want to happen when it is wrong? For example discard the entire csv, ignore than one row, collect the failures and present immediately to a human, collect somewhere and allow for a report. Might be some others.
You should also decide who actually manages it? Is it set up on install? Can it change day to day? Can different users change it (so not the customer but individual customer users.)
Those drive how you configure it. For example if install then you would need to ask that during install. (This probably is not viable since their needs might change over time.)
But other than that your application should have a section specifically for customer configurations. Yes plural. Presume one now and more for the future. And possible one for the application (admin users only) and one for normal users. You application might not support multiple users so the different levels might not apply.
With both application level and user level then you need to decide if the user one overrides the application one completely or if both work.
You can save the configuration in a configuration file or a database. Or other persistent store. You would normally load the configuration on start up. Naturally updates while running must impact the loaded configuration also.
|
|
|
|
|
I agree 100%, have some or other way to capture this to be used in the future, irrespective of which customer adds what as their own reference. Just do a callback then to that specific customer and you should be able to tie up the reference to the correct file reference.
|
|
|
|
|
I just started working with a business that made a web application that has a nodejs-expressjs backend api and a react front end. The business wants to sell its software as a white label solution to some enterprise sized businesses. My manager says that the customers will be expecting a detailed report to convince them that our solution is "secure". I need to determine steps to producing such a security report.
My first thoughts are to follow these steps:
1. Run the npm audit command on our backend and front end projects to identify all known vulnerabilities. And then fixed them according to recommended approaches I read about on the internet. This step has been done. The npm audit command shows no vulnerabilities or issues of any kind.
2. We upload our code as docker images to dockerhub.com. Dockerhub shows a list of vulnerabilities for us to address. I am currently in this step, and I have some issues which I will elaborate further down in this post.
3. Hire a 3rd party cyber security firm to test our solution. This firm will give us a report of issues to address.
That's my overall plan. However, I am currently stuck on step 2. Dockerhub is showing me MANY Critical and High priority vulnerabilities such as the following:
cve-2021-44906 - An Uncontrolled Resource Consumption flaw was found in minimist
https://access.redhat.com/security/cve/cve-2021-44906
CVE-2022-37434 - zlib through 1.2.12 has a heap-based buffer over-read or buffer overflow in inflate in inflate.c via a large gzip header extra field.
https://nvd.nist.gov/vuln/detail/CVE-2022-37434
...etc...
According to dockerhub, there are about 100 of these types of vulnerabilities, where maybe 10% are critical, 15% are high, rest are medium or low. These issues look very difficult to address, because they are used by modules of modules that I don't directly access in my own software. Trying to replace these modules of modules basically means a complete rewrite of our software to not depend on ANY open source solutions at all! And I'm sure if I were to scan packages with another type of scanner, different sets of vulnerabilities would be exposed. And I haven't even gotten to step 3 yet.
So this got me wondering...how do other organizations selling white labelled solutions go about disclosing vulnerabilities to their end clients and how do they protect themselves?
I started thinking that maybe I don't have to deal with every single security vulnerability that exists. Instead, I should only address security issues that I am confident hackers will exploit or things that are easy to address. Then I hire a security party firm to find other vulnerabilities. Anything that's not caught by the security firm we deem as "not important". And we develop some contract and service agreement that protects our business from the legal actions if our clients experiences a security vulnerability not covered in our report?
But then, a customer will say, "But dockerhub.com clearly shows vulnerability X, and you as the seller were aware of vulnerability X, please justify to us why you did not address it." And how do we respond then?
That's what's in my head right now.
So back to my original question - what steps should a team take to address security concerns of a software that will be white labelled and sold to customers?
|
|
|
|
|