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

Feature/nar 1913 bug spending limits js #532

Merged
merged 10 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .github/workflows/policy-engine.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,11 @@ jobs:
run: |
make install/ci

- name: Install Open Policy Agent CLI
uses: open-policy-agent/setup-opa@v2
with:
version: latest
- name: Download and install custom OPA
run: |
curl -L -o opa https://raw.githubusercontent.com/Ptroger/opa-bugfix-build/main/opa
chmod +x opa
sudo mv opa /usr/local/bin/opa

- name: Code format
shell: bash
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
Request,
SignMessageAction,
Then,
ValueOperators,
toHex
} from '@narval/policy-engine-shared'
import { SigningAlg, buildSignerEip191, hash, secp256k1PrivateKeyToJwk, signJwt } from '@narval/signature'
Expand Down Expand Up @@ -651,5 +652,289 @@ describe('OpenPolicyAgentEngine', () => {
expect(response.principal).toEqual(FIXTURE.CREDENTIAL.Alice)
})
})

describe('checkIntentAmount', () => {
const policies: Policy[] = [
{
id: 'can transfer 1 wei',
description: 'Permit to transfer up to 1 wei',
when: [
{
criterion: 'checkIntentAmount',
args: {
value: '1',
operator: 'lte' as ValueOperators
}
}
],
then: 'permit'
}
]

const entities = FIXTURE.ENTITIES

it('permits a transfer of 1 wei', async () => {
const e = await new OpenPolicyAgentEngine({
policies,
entities,
resourcePath: await getConfig('resourcePath')
}).load()

const request: Request = {
action: Action.SIGN_TRANSACTION,
nonce: 'test-nonce',
transactionRequest: {
from: '0x0301e2724a40E934Cce3345928b88956901aA127',
to: '0x76d1b7f9b3F69C435eeF76a98A415332084A856F',
value: '0x1',
chainId: 1
},
resourceId: 'eip155:eoa:0x0301e2724a40e934cce3345928b88956901aa127'
}

const evaluation: EvaluationRequest = {
authentication: await getJwt({
privateKey: FIXTURE.UNSAFE_PRIVATE_KEY.Bob,
sub: FIXTURE.USER.Bob.id,
request
}),
request
}

const response = await e.evaluate(evaluation)

expect(response.decision).toEqual(Decision.PERMIT)
})

it('forbids a transfer of 2 wei', async () => {
const e = await new OpenPolicyAgentEngine({
policies,
entities,
resourcePath: await getConfig('resourcePath')
}).load()

const request: Request = {
action: Action.SIGN_TRANSACTION,
nonce: 'test-nonce',
transactionRequest: {
from: '0x0301e2724a40E934Cce3345928b88956901aA127',
to: '0x76d1b7f9b3F69C435eeF76a98A415332084A856F',
value: '0x2',
chainId: 1
},
resourceId: 'eip155:eoa:0x0301e2724a40e934cce3345928b88956901aa127'
}

const evaluation: EvaluationRequest = {
authentication: await getJwt({
privateKey: FIXTURE.UNSAFE_PRIVATE_KEY.Bob,
sub: FIXTURE.USER.Bob.id,
request
}),
request
}

const response = await e.evaluate(evaluation)

expect(response.decision).toEqual(Decision.FORBID)
})

it('forbids a transfer of 9223372036854775295 wei', async () => {
const e = await new OpenPolicyAgentEngine({
policies,
entities,
resourcePath: await getConfig('resourcePath')
}).load()

const request: Request = {
action: Action.SIGN_TRANSACTION,
nonce: 'test-nonce',
transactionRequest: {
from: '0x0301e2724a40E934Cce3345928b88956901aA127',
to: '0x76d1b7f9b3F69C435eeF76a98A415332084A856F',
value: '0x7FFFFFFFFFFFFDFF',
chainId: 1
},
resourceId: 'eip155:eoa:0x0301e2724a40e934cce3345928b88956901aa127'
}

const evaluation: EvaluationRequest = {
authentication: await getJwt({
privateKey: FIXTURE.UNSAFE_PRIVATE_KEY.Bob,
sub: FIXTURE.USER.Bob.id,
request
}),
request
}

const response = await e.evaluate(evaluation)

expect(response.decision).toEqual(Decision.FORBID)
})

it('forbids a transfer of 9223372036854775296 wei', async () => {
const e = await new OpenPolicyAgentEngine({
policies,
entities,
resourcePath: await getConfig('resourcePath')
}).load()

const request: Request = {
action: Action.SIGN_TRANSACTION,
nonce: 'test-nonce',
transactionRequest: {
from: '0x0301e2724a40E934Cce3345928b88956901aA127',
to: '0x76d1b7f9b3F69C435eeF76a98A415332084A856F',
value: toHex(9223372036854775296n),
chainId: 1
},
resourceId: 'eip155:eoa:0x0301e2724a40e934cce3345928b88956901aa127'
}

const evaluation: EvaluationRequest = {
authentication: await getJwt({
privateKey: FIXTURE.UNSAFE_PRIVATE_KEY.Bob,
sub: FIXTURE.USER.Bob.id,
request
}),
request
}

const response = await e.evaluate(evaluation)

expect(response.decision).toEqual(Decision.FORBID)
})

it('forbids a transfer of rounded 9223372036854776000 wei', async () => {
const e = await new OpenPolicyAgentEngine({
policies,
entities,
resourcePath: await getConfig('resourcePath')
}).load()

const request: Request = {
action: Action.SIGN_TRANSACTION,
nonce: 'test-nonce',
transactionRequest: {
from: '0x0301e2724a40E934Cce3345928b88956901aA127',
to: '0x76d1b7f9b3F69C435eeF76a98A415332084A856F',
value: toHex(9223372036854776000n),
chainId: 1
},
resourceId: 'eip155:eoa:0x0301e2724a40e934cce3345928b88956901aa127'
}

const evaluation: EvaluationRequest = {
authentication: await getJwt({
privateKey: FIXTURE.UNSAFE_PRIVATE_KEY.Bob,
sub: FIXTURE.USER.Bob.id,
request
}),
request
}

const response = await e.evaluate(evaluation)

expect(response.decision).toEqual(Decision.FORBID)
})
it('forbids a transfer of 9223372036854775808 wei', async () => {
const e = await new OpenPolicyAgentEngine({
policies,
entities,
resourcePath: await getConfig('resourcePath')
}).load()

const request: Request = {
action: Action.SIGN_TRANSACTION,
nonce: 'test-nonce',
transactionRequest: {
from: '0x0301e2724a40E934Cce3345928b88956901aA127',
to: '0x76d1b7f9b3F69C435eeF76a98A415332084A856F',
value: toHex(9223372036854775808n),
chainId: 1
},
resourceId: 'eip155:eoa:0x0301e2724a40e934cce3345928b88956901aa127'
}

const evaluation: EvaluationRequest = {
authentication: await getJwt({
privateKey: FIXTURE.UNSAFE_PRIVATE_KEY.Bob,
sub: FIXTURE.USER.Bob.id,
request
}),
request
}

const response = await e.evaluate(evaluation)

expect(response.decision).toEqual(Decision.FORBID)
})
it('forbids a transfer of 18446744073709551617 wei', async () => {
const e = await new OpenPolicyAgentEngine({
policies,
entities,
resourcePath: await getConfig('resourcePath')
}).load()

const request: Request = {
action: Action.SIGN_TRANSACTION,
nonce: 'test-nonce',
transactionRequest: {
from: '0x0301e2724a40E934Cce3345928b88956901aA127',
to: '0x76d1b7f9b3F69C435eeF76a98A415332084A856F',
value: toHex(18446744073709552102n),
chainId: 1
},
resourceId: 'eip155:eoa:0x0301e2724a40e934cce3345928b88956901aa127'
}

const evaluation: EvaluationRequest = {
authentication: await getJwt({
privateKey: FIXTURE.UNSAFE_PRIVATE_KEY.Bob,
sub: FIXTURE.USER.Bob.id,
request
}),
request
}

const response = await e.evaluate(evaluation)

expect(response.decision).toEqual(Decision.FORBID)
})

// 10k eth
it('forbids a transfer of 10000000000000000000000 wei', async () => {
const e = await new OpenPolicyAgentEngine({
policies,
entities,
resourcePath: await getConfig('resourcePath')
}).load()

const request: Request = {
action: Action.SIGN_TRANSACTION,
nonce: 'test-nonce',
transactionRequest: {
from: '0x0301e2724a40E934Cce3345928b88956901aA127',
to: '0x76d1b7f9b3F69C435eeF76a98A415332084A856F',
value: toHex(10000000000000000000000n),
chainId: 1
},
resourceId: 'eip155:eoa:0x0301e2724a40e934cce3345928b88956901aa127'
}

const evaluation: EvaluationRequest = {
authentication: await getJwt({
privateKey: FIXTURE.UNSAFE_PRIVATE_KEY.Bob,
sub: FIXTURE.USER.Bob.id,
request
}),
request
}

const response = await e.evaluate(evaluation)

expect(response.decision).toEqual(Decision.FORBID)
})
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,33 @@ test_checkIntentAmountValue {
checkIntentAmount({"currency": "fiat:usd", "operator": operators.greaterThanOrEqual, "value": oneMaticValue}) with input as requestWithEip1559Transaction with data.entities as entities
checkIntentAmount({"currency": "fiat:usd", "operator": operators.lessThanOrEqual, "value": oneMaticValue}) with input as requestWithEip1559Transaction with data.entities as entities
}

test_checkIntentAmount2 {
requ := {
"action": "signTransaction",
"principal": {
"userId": "test-bob-user-uid",
"id": "0x7e431d5b570ba38e2e036387a596219ae9076e8a488a6149b491892b03582166",
},
"approvals": [{
"userId": "test-bob-user-uid",
"id": "0x7e431d5b570ba38e2e036387a596219ae9076e8a488a6149b491892b03582166",
}],
"intent": {
"to": "eip155:1:0x76d1b7f9b3f69c435eef76a98a415332084a856f",
"from": "eip155:1:0x0301e2724a40e934cce3345928b88956901aa127",
"type": "transferNative",
"amount": "9223372036854776000",
"token": "eip155:1/slip44:60",
},
"transactionRequest": {
"chainId": 1,
"from": "0x0301e2724a40e934cce3345928b88956901aa127",
"to": "0x76d1b7f9b3f69c435eef76a98a415332084a856f",
"value": "0x80000000000000c0",
},
"resource": {"uid": "eip155:eoa:0x0301e2724a40e934cce3345928b88956901aa127"},
}

checkIntentAmount({"operator": operators.greaterThanOrEqual, "value": "1"}) with input as requ
}
3 changes: 1 addition & 2 deletions deploy/policy-engine.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ FROM node:21 as build
WORKDIR /usr/src/app

# Install the OPA binary, which we'll need to actually run evals
RUN curl -L -o opa https://openpolicyagent.org/downloads/v0.64.1/opa_linux_amd64_static && \
RUN curl -L -o opa https://raw.githubusercontent.com/Ptroger/opa-bugfix-build/main/opa && \
chmod 755 opa && \
mv opa /usr/local/bin/opa && \
opa version
Expand Down Expand Up @@ -48,4 +48,3 @@ ENV RESOURCE_PATH=/usr/src/app/dist/apps/policy-engine/resource

EXPOSE 3010
CMD ["node", "dist/apps/policy-engine/main.js"]

Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const decodeNativeTransfer = (input: NativeTransferInput): TransferNative
chainId: input.chainId
}),
type: Intents.TRANSFER_NATIVE,
amount: Number(input.value).toString(),
amount: BigInt(input.value).toString(),
token: nativeCaip19(input.chainId)
}
}