Why is the exact difference between "violation" and "deny" in OPA/Rego? - open-policy-agent

In Open Policy Agent (https://www.openpolicyagent.org/)
regarding to Kubernetes, depending which engine is used:
Gatekeeper: https://github.com/open-policy-agent/gatekeeper
OR
Plain OPA with kube-mgmt: https://www.openpolicyagent.org/docs/latest/kubernetes-introduction/#how-does-it-work-with-plain-opa-and-kube-mgmt
There are different ways to define validation rules:
In Gatekeeper the violation is used. See sample rules here: https://github.com/open-policy-agent/gatekeeper-library/tree/master/library/general
In plain OPA samples, the deny rule, see sample here:
https://www.openpolicyagent.org/docs/latest/kubernetes-introduction/#how-does-it-work-with-plain-opa-and-kube-mgmt
It seems to be the OPA constraint framework defines it as violation:
https://github.com/open-policy-agent/frameworks/tree/master/constraint#rule-schema
So what is the exact "story" behind this, why it is not consistent between the different engines?
Notes:
This doc reflects on this: https://www.openshift.com/blog/better-kubernetes-security-with-open-policy-agent-opa-part-2
Here is mentioned how to support interoperability in the script: https://github.com/open-policy-agent/gatekeeper/issues/1168#issuecomment-794759747
https://github.com/open-policy-agent/gatekeeper/issues/168 In this issue is the migration mentioned, is just because of "dry run" support?.

Plain OPA has no opinion on how you choose to name your rules. Using deny is just a convention in the tutorial. The real Kubernetes admission review response is going to look something like this:
{
"kind": "AdmissionReview",
"apiVersion": "admission.k8s.io/v1beta1",
"response": {
"allowed": false,
"status": {
"reason": "container image refers to illegal registry (must be hooli.com)"
}
}
}
So whatever you choose to name your rules the response will need to be transformed into a response like the above before it's sent back to the Kubernetes API server. If you scroll down a bit in the Detailed Admission Control Flow section of the Kubernetes primer docs, you'll see how this transformation is accomplished in the system.main rule:
package system
import data.kubernetes.admission
main = {
"apiVersion": "admission.k8s.io/v1beta1",
"kind": "AdmissionReview",
"response": response,
}
default response = {"allowed": true}
response = {
"allowed": false,
"status": {
"reason": reason,
},
} {
reason = concat(", ", admission.deny)
reason != ""
}
Note in particular how the "reason" attribute is just built by concatenating all the strings found in admission.deny:
reason = concat(", ", admission.deny)
If you'd rather use violation or some other rule name using plain OPA, this is where you would change it.

Related

Is it possible to pass AWS EventBridge rule event variables to the target Invocation HTTP Parameters?

I am pretty sure I miss something simple but I don't seem to fins any resource on my issue and I am a novice on AWS.
The problem is as follows: I have a scenario where I would like to trigger a REST POST API when files are uploaded to an S3 bucket. This POST API uses OAuth 2.0 and requires the file name in the body.
I created a rule that successfully triggers on upload and the API works well if I put a static filename as Invocation Http Parameter. But I would like this value to be dynamic, based on the file that triggers the event.
I have tried using the jQuery snippet $.detail.object.key but, as much as it works for adding a Query Parameter from the rule, it doesn't seem to work if used in the Invocation Http Parameters settings in the API connection.
The event pattern is as follows:
{
"source": ["aws.s3"],
"detail-type": ["Object Created"],
"detail": {
"bucket": {
"name": ["jna-test-bucket"]
},
"object": {
"key": [{
"prefix": "testFileForAPI"
}]
}
}
}

Istio EnvoyFilter - Wasm - Classifying Metrics Based on Request or Response

I am trying to insert a custom dimension for an istio metric for URL path.
I am following the steps here -
https://istio.io/latest/docs/tasks/observability/metrics/classify-metrics/
Specifically, this part, where I can parse the URL and decide the value :
configuration:
"#type": type.googleapis.com/google.protobuf.StringValue
value: |
{
"attributes": [
{
"output_attribute": "istio_operationId",
"match": [
{
"value": "ListReviews",
"condition": "request.url_path == '/reviews' && request.method == 'GET'"
},
{
"value": "GetReview",
"condition": "request.url_path.matches('^/reviews/[[:alnum:]]*$') && request.method == 'GET'"
},
{
"value": "CreateReview",
"condition": "request.url_path == '/reviews/' && request.method == 'POST'"
}
]
}
]
}
I want to add a fall-back approach - i.e., if it doesn't match any URL, then make the value of istio_operationId as the original request.url_path
How can I do that?
I tried adding this as the last condition but it doesn't work
{
"value": "request.url_path", //tried without quotes as well
"condition": "request.url_path.matches('.+$')"
}
Also, is this possible in Lua?
To set a fall back value leave the condition blank. From the docs "An empty condition evaluates to true and should be used to provide a default value.".
That said, I don't think there's a way to set the attribute value to anything but a static string. What you can do instead is add the url_path as a dimension to one (or all) metrics generated by the stats filter. To say it another way, I don't think you can combine request classification with custom dimensions the way you're describing.
See this blog post for details as well as an explanation of the difference between attributes and dimensions.
Also, you may want to reconsider trying. When metrics are emitted with unbounded cardinality monitoring systems fall over. Here is a description of an Istio user crashing their Prometheus instance this way. Here is the (then) co-lead of the Istio extensions and telemetry working group discussing why they do not recommend doing this.

AzureBlobStorageOnIoTEdge: Error Target container connection not specified, upload turned off

My local blob storage is not uploading blobs to my cloud storage account. It reports back
"configurationValidation": {
"deviceAutoDeleteProperties": {
"deleteOn": {
"Status": "Success"
},
"deleteAfterMinutes": {
"Status": "Warning",
"Message": "Auto Delete after minutes value not specified, auto deletion turned off."
},
"retainWhileUploading": {
"Status": "Success"
}
},
"deviceToCloudUploadProperties": {
"uploadOn": {
"Status": "Success"
},
"cloudStorageAccountName": {
"Status": "Error",
"Message": "Target container connection not specified, upload turned off."
},
"cloudStorageAccountKey": {
"Status": "Error",
"Message": "Target container connection not specified, upload turned off."
},
"uploadOrder": {
"Status": "Success"
},
"deleteAfterUpload": {
"Status": "Success"
}
}
},
I am pretty sure that it should work. My desired properties are
"deviceToCloudUploadProperties": {
"uploadOn": true,
"uploadOrder": "OldestFirst",
"cloudStorageConnectionString": "DefaultEndpointsProtocol=https;AccountName=*****;AccountKey=******;EndpointSuffix=core.windows.net",
"storageContainersForUpload": {
"***": {
"target": "***"
}
},
"deleteAfterUpload": true
}
The container exists locally and on the cloud site. I copied the primary connection string from my local storage account into the configuration. The local storage is working, I can see that my container was created and contains data but it doesn't want to synchronize with the cloud. Why is it saying "Target container connection not specified, upload turned off."? It sounds like this part is missing
"storageContainersForUpload": {
"***": {
"target": "***"
}
},
but obviously it is not.
I'm using the latest docker image of this service. Is there any chance to use an older version? Some months ago I could make it work already. I tried to use a different version like mcr.microsoft.com/azure-blob-storage:1.4.0 but it doesn't accept any other tags than latest.
Thx!
The difference between my working version of the local blob storage module and my non working version was that the non working version was deployed by a deployment plan. In the deployment plan you cannot just paste the module twin settings of the documentation of the blob storage on IoT edge like https://learn.microsoft.com/en-us/azure/iot-edge/how-to-deploy-blob?view=iotedge-2020-11
You need to split the configuration into two parts where the first part looks like this
and the second part looks like that
And that totally makes sense. If you want to update your modules you probably want to keep your configuration because there might have been some changes which were made e.g. by a customer. This gives you the possibilty to add some properties to your inital configuration later without changing anything what was already configured. In fact every device can keep its individual configuration at any time.
My wrongly configured reported proterties were hidden in the suggested default path "properties.desired.settings" and thus the edge runtime could not find it.

Outgoing Webhook what is the format of the response message?

I have created an outgoing webhook in MS Teams. At mentioning the name specified in the outgoing webhook, it will successfully cause an API call in my app - all fine and good.
According to the documentation, my app is required to respond to that request with a response message. But I absolutely can't find any documentation of the format that is accepted in this response.
The only reference, I can find is this one:
https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-outgoing-webhook
Unfortunately, it does not go into detail of what such a message can look like. It only gives an example that this would be acceptable:
{
"type": "message",
"text": "This is a reply!"
}
I would however not like to respond with a simple message, but much rather with something more rich formatted like a card or - in some cases a reaction instead of a message.
Is that possible? Is there any documentation, what other responses are acceptable? Are there other types than just "message" that can be returned?
Alright, here's a quick and dirty way to handle things for teams. For some reason this is not documented very clearly, but what teams requires is for the "Card" to be created as an attachment, instead of just getting the response directly.
What I've done is capture the boilerplate required to house the card first:
string TeamsAdaptiveCardBoilerplate =
#"
{
""type"":""message"",
""attachments"":[
{
""contentType"":""application/vnd.microsoft.card.adaptive"",
""contentUrl"":null,
""content"":{
""$schema"":""http://adaptivecards.io/schemas/adaptive-card.json"",
""type"":""AdaptiveCard"",
""version"":""1.2"",
""body"":[
##BODY##
]
}
}
]
}
";
Then, I build the body (usually, this would not be static text, but it serves well as an example)
string AdaptiveCardBody =
#"
{
""type"": ""TextBlock"",
""text"": ""Here is a ninja cat""
},
{
""type"": ""Image"",
""url"": ""http://adaptivecards.io/content/cats/1.png""
}
";
Next I simple swap out the placeholder with the real body:
var jsonPayload1 = TeamsAdaptiveCardBoilerplate.Replace("##BODY##", AdaptiveCardBody);
And finally, return the assembled payload (converted back into an object so the correct response headers get set):
var payload1 = JsonConvert.DeserializeObject(jsonPayload1);
return (ActionResult)new OkObjectResult(payload1);
From there, you should be good to go.
Note:
For convenience, the entirety of the "content" (and not "body") block is what you'd copy/paste into the adaptivecards.io designer. You might refactor the above to reflect that reality if it was important to you.
Could you please try this sample json { "$schema": "adaptivecards.io/schemas/adaptive-card.json", "type": "AdaptiveCard", "version": "1.2", "body": [ { "type": "Image", "url": "c.s-microsoft.com/en-us/CMSImages/…" }, { "type": "TextBlock", "text": "Sample image for Adaptive Card..", "wrap": true } ] }

Documenting error codes definition in Swagger API contract

Imagine you are working under following circumstances:
You have REST API modules with API documentation generated into swagger-ui.html
Possible HTTP status codes for endpoints are documented well via io.swagger.annotations.* on controller method level for each endpoint.
In case of some error state (4XX or 5XX) application replies with ErrorResponseDTO with structure like
"ErrorResponseDTO": {
"type": "object",
"properties": {
"errorCode": {
"type": "integer",
"format": "int32"
},
"message": {
"type": "string"
}
}
}
Application have tens of errorCodes (within range like 1 - XX and please consider them as a legacy definiton without an easy way to change them).
List of errorCodes is relevant for the whole application so you prefer to keep their definiton list/table in overall API documentation rather then maintaining errorCodes definiton for each API endpoint separately.
Now you are looking for an effective way how to document these application error codes into API contract.
The approach of including a list of errorCodes with codes description into generated swagger-ui.html seems like a better way to keep API documentation up to date instead of having static and handwritten codes definition table attached in Markdown format in some Readme file.
Would you please have any recommendation how to document various codes which your applications produce?
Do you follow some specific good practice in this topic?
Thank you in advance.
Meanwhile within a small internal dev team and with frequent API extensions there can be used generated swagger-ui with included error codes:
#Bean
public Docket swaggerSettings() {
ApiSelectorBuilder builder = new Docket(DocumentationType.SWAGGER_2)
.apiInfo(
new ApiInfoBuilder()
.title("Response errorCodes table")
.description(RestResponse.generateErrorsDocumentation().toString())
.build()
)
...
.select();
return builder.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
.paths(PathSelectors.any())
.build()
.useDefaultResponseMessages(false);
}

Resources