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

Challenges in trying to use the NPM OPA module with Typescript #36

Closed
tvvignesh opened this issue Dec 18, 2020 · 8 comments
Closed

Challenges in trying to use the NPM OPA module with Typescript #36

tvvignesh opened this issue Dec 18, 2020 · 8 comments

Comments

@tvvignesh
Copy link

tvvignesh commented Dec 18, 2020

Hi. I have been trying to use this module with Node and Typescript with WASM but have been facing quite a few challenges. Thought of adding all of it in this issue.

  1. Old Package in NPM and also without Types

I initially tried installing the package from NPM and the examples did not work since the package was last published 1 year ago and there has been some breaking changes since then. For instance, load_policy has become loadPolicy and so on. Currently, downloaded this repo and working with it. I guess it is tracked by #31

  1. Lack of ES Module support

This module is based on commonjs and considering ES Modules is the standard, providing support for that would be great. Currently, working with esModuleInterop and importing like this:

import opa from "@open-policy-agent/opa-wasm";
const { loadPolicy } = opa;
  1. Inability to do some basic operations

While using this, I wanted to check whether the data has actually been loaded when I do setData but this module currently does not expose any API for getting the data which is loaded. I wanted to know the structure of the data loaded and also confirm that the data is available but all I am able to get back now if I do console.log(policy) is this from which I am not sure how to infer:

2

  1. I get a standard Boolean result always (Fixed: This was a mistake on my end)

I am not sure if I am doing something wrong here, but when I do evaluate the response I get is just one of these:

[ { result: true } ]

or

[ { result: false } ]

which is inconsistent with the results I am getting in the Playground or VSCode extension for the same rego files, data and input.

For instance, my output in playground looked something like this:

{
    "myrule": [
        {
            "msg": "test failed"
        }
    ],
    "testOutput": "test failed"
}

Also, while OPA WASM supports non-boolean results now as per this: open-policy-agent/opa#1118 I am not sure if this module does support it.

Thanks.

CC: @tsandall @patrick-east

@tvvignesh
Copy link
Author

In the same context, I have wrapped all these operations and am using it like this:

import opa from "@open-policy-agent/opa-wasm";
import { readFileSync } from 'fs';

const { loadPolicy } = opa;

let policy;

export const initPolicy = async function(filePath:string) {
  const policyWasm = readFileSync(filePath);
  policy = await loadPolicy(policyWasm);
  return policy;
};

export const loadData = function(data:any) {
  try {
    policy.setData(data);
  } catch (err) {
    console.error("Failed to load policy: " + err);
  }
};

export const evaluatePolicyJSON = function(input) {
  try {

    const inputRules = JSON.stringify(input);

    console.log('Evaluating policy::', inputRules);

    const result = policy.evaluate(inputRules);

    console.log('Result::', result);

    return result;
  } catch (err) {
    console.error('Error in evaluating policy::', err);
  }
};

export const evaluatePolicy = function(context, operation, resourcePath, resourceID) {

  const decision = evaluatePolicyJSON({
    context: context,
    operation: operation,
    resourcePath: resourcePath,
    resourceID: resourceID
  });

  return decision;
};

@srenatus
Copy link
Contributor

srenatus commented Dec 18, 2020

Thanks again for opening this detailed issue. It's much appreciated, I'd love to know more about everyone's stumbling blocks when adopting OPA's WASM.

On your notes, yes, we need an npm release, and I suppose we'd better automate that process, as laid out in #31.

Data introspection

Yeah there's currently no way to use given primitives to look at the data. However, what you can do is define another entrypoint:

$ cat t.rego
package t

p {
  1+1 == 2
}
$ opa build -t wasm -e t/p -e '' t.rego

you would then be able to select an entrypoint for evaluate. The "empty" entrypoint corresponds to a query for all of data, (you could also write -e 'x := data', I suppose). In the example policy, you'd get

$ node  run.js
[
  { result: { t: { p: true } } }
]

However, it doesn't look like multiple entrypoints were currently supported. I'll get another issue ready for that.

Non-boolean results

As shown in the example above, too, this is supported. How did you build the WASM module?

This was referenced Dec 18, 2020
@tvvignesh
Copy link
Author

tvvignesh commented Dec 18, 2020

@srenatus Thanks for the elaborate answer. This is how I built the WASM module taking inspiration from the repo.

opa build -t wasm -e 'main/allow' ./packages/shared/*.rego ./packages/modules/**/*.rego && tar -xzf ./bundle.tar.gz /policy.wasm && mv bundle.tar.gz ./packages/shared/bundle && mv policy.wasm ./packages/shared/bundle

I have a monorepo and I am using multiple .rego files for each package in my workspace (PNPM) and bundled it all together using wildcards. After doing this, I extracted the bundle, and I had all the rego files within. This is how my extracted bundle looks like:

1

NOTE: The data.json file has no data or rather {} but I guess that should be okay considering I am using setData to load the data dynamically in runtime (not sure). I did not want to preload the data but follow this: https://www.openpolicyagent.org/docs/latest/external-data/#option-5-pull-data-during-evaluation

Did not know that multiple entrypoints like that would give me data, but I did try defining something like x := data in the same rego file and got a recursion error.

But the interesting thing is that, even when I did assign a normal string like x := "Hello" I did not get x in the output (unlike playground or VSCode). I still got only result in the output. Not sure why.

Thanks.

@srenatus
Copy link
Contributor

Did not know that multiple entrypoints like that would give me data, but I did try defining something like x := data in the same rego file and got a recursion error.

That's the thing, you can query for anything; and in WASM, entrypoints are how you define queries. But you cannot have a rule that does that, since that's recursion.

Given that you've declared the entrypoint main/allow, corresponding to a query for data.main.allow, the boolean answer doesn't surprise, does it? Try changing that to -e 'main' or -e '' and you should see different results.

Could you provide an example of a complete policy document where the playground answer differs form the WASM answer? It might help understanding the issue.

@tvvignesh
Copy link
Author

@srenatus Ahh. Now I understand what you are saying. I feel stupid 😂 Let me try it out changing the entrypoint. Sorry, just starting off with OPA and I am pretty much a noob to this.

Could you provide an example of a complete policy document where the playground answer differs form the WASM answer? It might help understanding the issue.

I guess the entypoint problem you pointed out might be the cause for this. Will debug this and get back.

@srenatus
Copy link
Contributor

Oh no need to feel stupid. It's a lot to take in, OPA, and its (experimental) WASM stuff. 😃

@tvvignesh
Copy link
Author

UPDATE: @srenatus As you rightly said, changing the entrypoint did work. Able to evaluate and get the results properly which means that point 4 is invalid. And since I am able to evaluate now, I have verified that the data is successfully loaded by trying out different test cases. The output is consistent as per VSCode and playground.

Thanks.

@srenatus srenatus mentioned this issue Feb 5, 2021
2 tasks
@srenatus
Copy link
Contributor

srenatus commented Feb 8, 2021

With the release done and the issues spun off of this one, I think this can be closed. Please re-open if you think otherwise 😃

@srenatus srenatus closed this as completed Feb 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants