-
Notifications
You must be signed in to change notification settings - Fork 3
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
Rego template endpoint #96
Conversation
apps/authz/src/app/http/rest/dto/policy-criterion-builder.dto.ts
Outdated
Show resolved
Hide resolved
@@ -84,4 +87,10 @@ export class AdminService { | |||
|
|||
return payload.request.data | |||
} | |||
|
|||
async setPolicyRules(payload: SetPolicyRulesRequest): Promise<PolicyCriterionBuilder[]> { | |||
await this.opaService.generateRegoFile(payload.request.data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you plan to save these policies in the database as well, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes but not on the engine part. see this discussion:
https://narvalxyz.slack.com/archives/C067Q1TDA9G/p1707310563319479
generateRegoFile(policies: PolicyCriterionBuilder[]): void { | ||
Handlebars.registerHelper('criterion', function (item) { | ||
const criterion: Criterion = item.criterion | ||
const args = item.args | ||
|
||
if (args === null) { | ||
return `${criterion}` | ||
} | ||
|
||
if (!isEmpty(args)) { | ||
if (Array.isArray(args)) { | ||
if (typeof args[0] === 'string') { | ||
return `${criterion}({${args.map((el) => `"${el}"`).join(', ')}})` | ||
} | ||
|
||
if (criterion === Criterion.CHECK_APPROVALS) { | ||
return `approvals = ${criterion}([${args.map((el) => JSON.stringify(el)).join(', ')}])` | ||
} | ||
|
||
return `${criterion}([${args.map((el) => JSON.stringify(el)).join(', ')}])` | ||
} | ||
|
||
return `${criterion}(${JSON.stringify(args)})` | ||
} | ||
}) | ||
|
||
Handlebars.registerHelper('reason', function (item) { | ||
if (item.then === Then.PERMIT) { | ||
const reason = [ | ||
`"type": "${item.then}"`, | ||
`"policyId": "${item.name}"`, | ||
'"approvalsSatisfied": approvals.approvalsSatisfied', | ||
'"approvalsMissing": approvals.approvalsMissing' | ||
] | ||
return `reason = {${reason.join(', ')}}` | ||
} | ||
|
||
if (item.then === Then.FORBID) { | ||
const reason = { | ||
type: item.then, | ||
policyId: item.name, | ||
approvalsSatisfied: [], | ||
approvalsMissing: [] | ||
} | ||
return `reason = ${JSON.stringify(reason)}` | ||
} | ||
}) | ||
|
||
const templateSource = readFileSync('./apps/authz/src/opa/template/template.hbs', 'utf-8') | ||
|
||
const template = Handlebars.compile(templateSource) | ||
|
||
const regoContent = template({ policies }) | ||
|
||
writeFileSync(`./apps/authz/src/opa/rego/generated/${uuidv4()}.rego`, regoContent, 'utf-8') | ||
|
||
console.log('Policy .rego file generated successfully.') | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's a suggestion on how to unit test this logic:
- Separate side effects from policy generation logic. If you move the template file reading and Rego file writing elsewhere, the logic essentially becomes: given a policy schema and a template string, you produce a policy string on the other side (the Rego logic).
- Unit test each criterion defined in
policy-build.type.ts
. For a given template and criterion A, specify what you expect as a policy. Do this without merging criteria into a single policy. This approach will provide comprehensive documentation of what you expect for smaller system components. - Unit test a few criteria together to generate a policy and check if the outcome matches your expectations. This will provide us confidence on criteria composition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These types of logic to map from standard A to B are often a major source of bugs. Let's get that covered so we can move faster without breaking things 😉
No description provided.