Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

We need a Policy object #592

Open
ahouseholder opened this issue Jun 28, 2024 · 7 comments
Open

We need a Policy object #592

ahouseholder opened this issue Jun 28, 2024 · 7 comments
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@ahouseholder
Copy link
Contributor

Describe the solution you'd like

The PolicyGenerator object can be used to generate a CSV formatted policy, but we should really have a separate object to represent a policy.

See also #591

@ahouseholder ahouseholder added the enhancement New feature or request label Jun 28, 2024
@ahouseholder
Copy link
Contributor Author

If we refactor the Decision Point Group schema to pull out the decision_points array into a separate schema, that list could be partly the basis of the new schema.

@ahouseholder
Copy link
Contributor Author

Any resolution of this issue (#592) should take into account solutions to

@ahouseholder ahouseholder self-assigned this Feb 25, 2025
@ahouseholder ahouseholder added this to the 2025-03 milestone Feb 25, 2025
@ahouseholder
Copy link
Contributor Author

So I have a sketch of this in a local branch. The structure is as follows:

class DecisionFramework(_Versioned, _Namespaced, _Base, BaseModel):
    """
    The DecisionFramework class is a model for decisions in SSVC.

    It is a collection of decision points and outcomes, and a mapping of decision points to outcomes.

    The mapping is generated by the PolicyGenerator class, and stored as a dictionary.
    The mapping dict keys are decision point namespace:key:version:value.
    The mapping dict values are outcome group name:version:value.
    """

    decision_point_group: SsvcDecisionPointGroup
    outcome_group: OutcomeGroup
    mapping: dict[str, str]

    def __init__(self, **data):
        super().__init__(**data)

        if not self.mapping:
            self.mapping = self.generate_mapping()
...

I'm leaving out the generate_mapping() method as it's big and relies on the policy_generator module, but assume that it returns a d[str]=str.

I am attaching an example based on the decision point group for the Supplier model, except using a different ("MoSCoW") outcome set to make it clear that this is an example. It's far too large to include directly in this comment.

example.json

Concerns I can see already:

  1. We chose to represent the "full version" of the decision models (with no compound decision points) rather than the notationally compact ones with compound decision points. So the full combinatorics of Utility and Value Density are on display in the above example. This blows the table up to 360 rows.
  2. The keys and values for the mapping dict are rather verbose. The next few points expand on this.
  3. However, since we could have a DecisionFramework object that contains decision points from different namespaces, it seems necessary to include the namespace as part of the identity.
  4. Including the version string may be superfluous if we choose semantics that say "the decision points and outcome groups listed in the object are assumed to be the exact ones referenced in the mapping. That seems like a reasonable thing to do.
  5. We have a choice to make whether we use decision point name or key in the representation here. Choosing key (as shown) implies that we need to continue supporting the key indefinitely, which we had been trying to get away from for a while.
  6. If we are going to use keys instead of decision point names, we probably need a rule for a decision point group that says that all "namespace:key" values in a decision point group must be unique.
  7. Extending that, we may also need a rule that says all keys within a namespace must be unique. Logic also says that "names" should be unique within a namespace. Not sure if we've written that down already in an ADR.
  8. If we're going to use delimited strings as keys or values, we may need to prohibit those delimiters in the values they are constructed from. For example, the commas in the outcome group name ("Must, Should,...") could be a parsing problem downstream.
  9. Outcome Groups have neither namespaces nor keys, should they? I can see how "cvss:low" might be different from "nciss:low" for example. Also, obvious parallels to decision points.
  10. We should be explicit about case sensitivity in names and keys. By convention we seem to use Initial Caps for names and ALL_CAPS for keys, but we don't say whether these are case sensitive or not. My preference is that case is a human readability feature but any uniqueness requirements should be based on case-insensitivity. (exploitation is Exploitation is eXplOiTatiON). I believe we already established this precedent in the .csv files where we folded values to lowercase.

@ahouseholder
Copy link
Contributor Author

Based items 3, 4, 5 above, we might transform

"ssvc:E:1.0.0:None,ssvc:U:1.0.1:Laborious,ssvc:TI:1.0.0:Total,ssvc:A:2.0.0:No,ssvc:VD:1.0.0:Concentrated,ssvc:SI:1.0.0:Major": "Must, Should, Could, Won't:1.0.0:Won't",
"ssvc:E:1.0.0:None,ssvc:U:1.0.1:Laborious,ssvc:TI:1.0.0:Total,ssvc:A:2.0.0:No,ssvc:VD:1.0.0:Concentrated,ssvc:SI:1.0.0:Hazardous": "Must, Should, Could, Won't:1.0.0:Could",
"ssvc:E:1.0.0:None,ssvc:U:1.0.1:Laborious,ssvc:TI:1.0.0:Total,ssvc:A:2.0.0:No,ssvc:VD:1.0.0:Concentrated,ssvc:SI:1.0.0:Catastrophic": "Must, Should, Could, Won't:1.0.0:Should",

into:

"ssvc:E:None,ssvc:U:Laborious,ssvc:TI:Total,ssvc:A:No,ssvc:VD:Concentrated,ssvc:SI:Major": "Must, Should, Could, Won't:Won't",
"ssvc:E:None,ssvc:U:Laborious,ssvc:TI:Total,ssvc:A:No,ssvc:VD:Concentrated,ssvc:SI:Hazardous": "Must, Should, Could, Won't:Could",
"ssvc:E:None,ssvc:U:Laborious,ssvc:TI:Total,ssvc:A:No,ssvc:VD:Concentrated,ssvc:SI:Catastrophic": "Must, Should, Could, Won't:Should",

We could further shrink this by:

  • use Decision Point Value Keys instead of Names
  • add keys to Outcome Group objects

and bring it down to (different example rows, but you get the idea)

"ssvc:E:A,ssvc:U:S,ssvc:TI:T,ssvc:A:N,ssvc:VD:D,ssvc:SI:N": "MOSCOW:C",
"ssvc:E:A,ssvc:U:S,ssvc:TI:T,ssvc:A:N,ssvc:VD:D,ssvc:SI:M": "MOSCOW:S",
"ssvc:E:A,ssvc:U:S,ssvc:TI:T,ssvc:A:N,ssvc:VD:D,ssvc:SI:J": "MOSCOW:S",
"ssvc:E:A,ssvc:U:S,ssvc:TI:T,ssvc:A:N,ssvc:VD:D,ssvc:SI:H": "MOSCOW:M",

which, again assuming that this list ONLY appears in the context of a DecisionFramework object that dereferences all the various keys to specific versions of objects, seems like it'd be okay.

The risk is that these strings start looking like CVSS vectors again, and they may get copied outside of the context of the json blob we're talking about. In which case there could be some ambiguity over time as decision points or outcome groups bump versions.

@j---
Copy link
Collaborator

j--- commented Mar 4, 2025

Thanks Allan! Can we think about the display issue as a usability issue? Even if it is just usability for developers and people working with the software, we still might want to look at it from a usability lens to make sure that the tasks the users want to accomplish are easy. We may need to somehow get to a usability discussion for leadership reviewing and approving a risk stance that might be better addressed through a visualization, not text. If that's the case, compressing the string to look more like a CVSS string may not be the best solution to the usability issue. But I am noting the convergent evolution forces that maybe lead to a CVSS vector string.

@ahouseholder
Copy link
Contributor Author

Can we think about the display issue as a usability issue? Even if it is just usability for developers and people working with the software, we still might want to look at it from a usability lens to make sure that the tasks the users want to accomplish are easy. We may need to somehow get to a usability discussion for leadership reviewing and approving a risk stance that might be better addressed through a visualization, not text. If that's the case, compressing the string to look more like a CVSS string may not be the best solution to the usability issue. But I am noting the convergent evolution forces that maybe lead to a CVSS vector string.

I agree there's a usability concern here if we were to expect humans to be working directly with that JSON object in the course of "doing SSVC". I don't think that's the case here. I am thinking of this as a machinable object that happens to be human-readable by experts but is not intended for most folks to ever directly see.

I'm going to suggest that if anyone but a programmer or programmer-adjacent role is looking at this data representation, they're in the wrong place, and we should be able to redirect them to an alternative way of presenting this object that is actually human-consumable. So yes, we need a way of presenting this object to an "SSVC user" who expects to see text in tables or formatted lists etc., but not raw JSON. But I think that's more in the "Policy Explorer" UI side than it is about this object model.

And yes, the "carcinization, but for CVSS" thing is not lost on me. 🦀

@j---
Copy link
Collaborator

j--- commented Mar 11, 2025

I agree with this; we would need a way to redirect folks who are not programmers.

In addition, programmers are humans and have usability needs. The usability needs on producing accurate, functional, and review-able code are non-trivial. What solution best meets those usability needs? (or different / additional usability needs that may be better). And meets them for a wide group of different programmers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

When branches are created from issues, their pull requests are automatically linked.

2 participants