Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/npm_and_yarn/bull-board/api-5.13.0
Browse files Browse the repository at this point in the history
  • Loading branch information
wcalderipe committed Jan 23, 2024
2 parents 9e42b50 + 898f7a2 commit e05827f
Show file tree
Hide file tree
Showing 102 changed files with 2,331 additions and 937 deletions.
17 changes: 17 additions & 0 deletions .github/workflows/authz_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,20 @@ jobs:
fields: message,commit,author
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}

opa-rego:
name: Open Agent Policy CI

runs-on: ubuntu-latest

steps:
- name: Check out repository code
uses: actions/checkout@v3

- name: Setup OPA
uses: open-policy-agent/setup-opa@v2
with:
version: latest

- name: Run OPA Tests
run: make authz/rego/test
25 changes: 25 additions & 0 deletions .github/workflows/authz_opa_ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: '@app/authz OPA CI'

on:
push:
paths:
- apps/authz/src/opa/rego/**
- .github/workflows/authz_opa_ci.yml

jobs:
opa-rego:
name: Open Agent Policy CI

runs-on: ubuntu-latest

steps:
- name: Check out repository code
uses: actions/checkout@v3

- name: Setup OPA
uses: open-policy-agent/setup-opa@v2
with:
version: latest

- name: Run OPA Tests
run: make authz/rego/test
5 changes: 5 additions & 0 deletions .github/workflows/transaction_request_intent_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ jobs:
run: |
make transaction-request-intent/test/type
- name: Test upstream application types
shell: bash
run: |
make authz/test/type
- name: Test unit
shell: bash
run: |
Expand Down
1 change: 1 addition & 0 deletions .husky/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
_
4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx lint-staged
6 changes: 6 additions & 0 deletions apps/authz/.lintstagedrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
'*.{ts,tsx}': (filenames) => [
`eslint --no-error-on-unmatched-pattern ${filenames.join(' ')}; echo "ESLint completed with exit code $?"`,
`prettier --write ${filenames.join(' ')}`
]
}
23 changes: 13 additions & 10 deletions apps/authz/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,36 +53,39 @@ authz/rego/compile:
opa build \
--target wasm \
--entrypoint main/evaluate \
--bundle ${AUTHZ_PROJECT_DIR}/src/app/opa/rego \
--bundle ${AUTHZ_PROJECT_DIR}/src/opa/rego \
--ignore "__test__" \
--output ./rego-build/policies.gz
tar -xzf ./rego-build/policies.gz -C ./rego-build/

authz/rego/wasm:
npx ts-node \
--compiler-options "{\"module\":\"CommonJS\"}" \
${AUTHZ_PROJECT_DIR}/src/app/opa/rego/script.ts
${AUTHZ_PROJECT_DIR}/src/opa/rego/script.ts

authz/rego/bundle:
rm -rf ${AUTHZ_PROJECT_DIR}/src/app/opa/build
rm -rf ${AUTHZ_PROJECT_DIR}/src/opa/build

mkdir -p ${AUTHZ_PROJECT_DIR}/src/app/opa/build
mkdir -p ${AUTHZ_PROJECT_DIR}/src/opa/build

opa build \
--bundle ${AUTHZ_PROJECT_DIR}/src/app/opa/rego \
--bundle ${AUTHZ_PROJECT_DIR}/src/opa/rego \
--ignore "__test__" \
--output ${AUTHZ_PROJECT_DIR}/src/app/opa/build/policies.tar.gz
--output ${AUTHZ_PROJECT_DIR}/src/opa/build/policies.tar.gz

authz/rego/eval:
opa eval \
--format="pretty" \
--bundle ${AUTHZ_PROJECT_DIR}/src/app/opa/build/policies.tar.gz \
--input ${AUTHZ_PROJECT_DIR}/src/app/opa/rego/input.json \
--bundle ${AUTHZ_PROJECT_DIR}/src/opa/build/policies.tar.gz \
--input ${AUTHZ_PROJECT_DIR}/src/opa/rego/input.json \
'data.main.evaluate'

authz/rego/test:
opa test \
--format="pretty" \
${AUTHZ_PROJECT_DIR}/src/app/opa/rego \
${AUTHZ_PROJECT_DIR}/src/opa/rego \
--verbose \
--watch
${ARGS}

authz/rego/test/watch:
make authz/rego/test ARGS=--watch
17 changes: 12 additions & 5 deletions apps/authz/src/app/app.controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { EvaluationRequestDto } from '@app/authz/app/evaluation-request.dto'
import { generateInboundRequest } from '@app/authz/shared/module/persistence/mock_data'
import { AuthZRequestPayload } from '@app/authz/shared/types/domain.type'
import { AuthorizationRequestPayload } from '@app/authz/shared/types/domain.type'
import { Body, Controller, Get, Logger, Post } from '@nestjs/common'
import { AppService } from './app.service'

Expand All @@ -27,11 +27,12 @@ export class AppController {
@Post('/evaluation')
async evaluate(@Body() body: EvaluationRequestDto) {
this.logger.log({
message: 'Received evaluation'
message: 'Received evaluation',
body
})

// Map the DTO into the TS type because it's nicer to deal with.
const payload: AuthZRequestPayload = body
const payload: AuthorizationRequestPayload = body

const result = await this.appService.runEvaluation(payload)
this.logger.log({
Expand All @@ -44,10 +45,11 @@ export class AppController {

@Post('/evaluation-demo')
async evaluateDemo() {
const fakeRequest = await generateInboundRequest()
this.logger.log({
message: 'Received evaluation'
message: 'Received evaluation',
body: fakeRequest
})
const fakeRequest = await generateInboundRequest()
const result = await this.appService.runEvaluation(fakeRequest)
this.logger.log({
message: 'Evaluation Result',
Expand All @@ -59,4 +61,9 @@ export class AppController {
result
}
}

@Get('/generate-inbound-request')
generateInboundRequest() {
return generateInboundRequest()
}
}
74 changes: 45 additions & 29 deletions apps/authz/src/app/app.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ import { PersistenceRepository } from '@app/authz/shared/module/persistence/pers
import {
Alg,
AuthCredential,
AuthZRequest,
AuthZRequestPayload,
AuthZResponse,
AuthorizationRequest,
AuthorizationRequestPayload,
AuthorizationResponse,
HistoricalTransfer,
NarvalDecision,
RequestSignature
} from '@app/authz/shared/types/domain.type'
import { OpaResult, RegoInput } from '@app/authz/shared/types/rego'
import { hashRequest } from '@narval/authz-shared'
import { Action, hashRequest } from '@narval/authz-shared'
import { Injectable } from '@nestjs/common'
import { Decoder } from 'packages/transaction-request-intent/src'
import { InputType } from 'packages/transaction-request-intent/src/lib/domain'
Expand Down Expand Up @@ -75,7 +75,14 @@ export class AppService {
address,
signature: signature as Hex
})
if (!valid) throw new Error('Invalid Signature')
if (!valid) {
console.log('### invalid', {
pubKey,
sig
})

throw new Error('Invalid Signature')
}
}
// TODO: verify other alg types

Expand Down Expand Up @@ -104,47 +111,56 @@ export class AppService {
transfers
}: {
principal: AuthCredential
request: AuthZRequest
request: AuthorizationRequest
approvals: AuthCredential[] | null
intent?: Intent
transfers?: HistoricalTransfer[]
}): RegoInput {
// intent only exists in SignTransaction actions
return {
action: request.action,
intent,
transactionRequest: request.transactionRequest,
principal,
resource: request.resourceId
? {
uid: request.resourceId
}
: undefined,
approvals: approvals || [],
transfers: transfers || []
if (request.action === Action.SIGN_TRANSACTION) {
return {
action: Action.SIGN_TRANSACTION,
intent,
transactionRequest: request.transactionRequest,
principal,
resource: request.resourceId
? {
uid: request.resourceId
}
: undefined,
approvals: approvals || [],
transfers: transfers || []
}
}

throw new Error(`Unsupported action ${request.action}`)
}

/**
* Actual Eval Flow
*/
async runEvaluation({ request, authentication, approvals, transfers }: AuthZRequestPayload) {
async runEvaluation({ request, authentication, approvals, transfers }: AuthorizationRequestPayload) {
// Pre-Process
// verify the signatures of the Principal and any Approvals
const decoder = new Decoder()
const decoder = new Decoder({})
const verificationMessage = hashRequest(request)

const principalCredential = await this.#verifySignature(authentication, verificationMessage)
if (!principalCredential) throw new Error(`Could not find principal`)
const populatedApprovals = await this.#populateApprovals(approvals, verificationMessage)

// Decode the intent
const intentResult = request.transactionRequest
? decoder.safeDecode({
type: InputType.TRANSACTION_REQUEST,
txRequest: request.transactionRequest
})
: undefined
if (intentResult?.success === false) throw new Error(`Could not decode intent: ${intentResult.error.message}`)
const intentResult =
request.action === Action.SIGN_TRANSACTION
? decoder.safeDecode({
type: InputType.TRANSACTION_REQUEST,
txRequest: request.transactionRequest
})
: undefined

if (intentResult?.success === false) {
throw new Error(`Could not decode intent: ${intentResult.error.message}`)
}

const intent = intentResult?.intent

const input = this.#buildRegoInput({
Expand All @@ -163,7 +179,7 @@ export class AppService {
// Post-processing to evaluate multisigs
const finalDecision = finalizeDecision(resultSet)

const authzResponse: AuthZResponse = {
const authzResponse: AuthorizationResponse = {
decision: finalDecision.decision,
request,
totalApprovalsRequired: finalDecision.totalApprovalsRequired,
Expand Down
32 changes: 19 additions & 13 deletions apps/authz/src/app/evaluation-request.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,20 @@ export class TransactionRequestDto {
}

export class SignTransactionRequestDataDto extends BaseRequestDataDto {
@IsEnum(Action)
@IsDefined()
@ApiProperty({
enum: Action,
default: Action.SIGN_TRANSACTION
})
action: Action.SIGN_TRANSACTION

@IsString()
@IsDefined()
@ApiProperty()
resourceId: string

@ValidateNested()
@Type(() => TransactionRequestDto)
@IsDefined()
@ApiProperty({
type: TransactionRequestDto
Expand All @@ -111,6 +118,14 @@ export class SignTransactionRequestDataDto extends BaseRequestDataDto {
}

export class SignMessageRequestDataDto extends BaseRequestDataDto {
@IsEnum(Action)
@IsDefined()
@ApiProperty({
enum: Action,
default: Action.SIGN_MESSAGE
})
action: Action.SIGN_MESSAGE

@IsString()
@IsDefined()
@ApiProperty()
Expand Down Expand Up @@ -139,6 +154,8 @@ export class EvaluationRequestDto {
@ApiProperty()
authentication: RequestSignatureDto

@IsOptional()
@ValidateNested()
@ApiProperty({
type: () => RequestSignatureDto,
isArray: true
Expand All @@ -157,19 +174,8 @@ export class EvaluationRequestDto {
})
request: SignTransactionRequestDataDto | SignMessageRequestDataDto

@IsOptional()
@ValidateNested()
@ApiProperty()
transfers?: HistoricalTransferDto[]

isSignTransaction(
request: SignTransactionRequestDataDto | SignMessageRequestDataDto
): request is SignTransactionRequestDataDto {
return this.request.action === Action.SIGN_TRANSACTION
}

isSignMessage(
request: SignTransactionRequestDataDto | SignMessageRequestDataDto
): request is SignMessageRequestDataDto {
return this.request.action === Action.SIGN_MESSAGE
}
}
Loading

0 comments on commit e05827f

Please sign in to comment.