Skip to content

Commit

Permalink
feat: Beginning of the resolveTrustChains
Browse files Browse the repository at this point in the history
Signed-off-by: Tom Lanser <[email protected]>
  • Loading branch information
Tommylans committed Nov 5, 2024
1 parent 3019442 commit 6c8bc37
Show file tree
Hide file tree
Showing 7 changed files with 352 additions and 2 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
},
"devDependencies": {
"@biomejs/biome": "1.8.3",
"rimraf": "^6.0.0"
"rimraf": "^6.0.0",
"tsx": "^4.19.2"
},
"pnpm": {
"overrides": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,12 @@ export const fetchEntityStatementChain = async ({
}

// The trust anchors (i.e. the last item of the list) entity configuration will be used instead of a statement issued by a superior
return [entityConfigurations[entityConfigurations.length - 1], ...(await Promise.all(promises))].reverse()

const trustAnchorEntityConfiguration = entityConfigurations[entityConfigurations.length - 1]
// Should never happen because there will always be a trust anchor in a valid chain
if (!trustAnchorEntityConfiguration) {
throw new OpenIdFederationError(ErrorCode.Validation, 'No trust anchor entity configuration found')
}

return [trustAnchorEntityConfiguration, ...(await Promise.all(promises))].reverse()
}
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export * from './constraints'
export * from './entityConfiguration'
export * from './entityStatement'
export * from './resolveTrustChains'
export * from './jsonWeb'
export * from './metadata'
export * from './trustMark'
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/metadata/metadataPolicy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ export const metadataPolicySchema = z.object({
[oauthClientEntityMetadata.identifier]: oauthClientEntityMetadata.policySchema.optional(),
[oauthResourceEntityMetadata.identifier]: oauthResourceEntityMetadata.policySchema.optional(),
})

export type MetadataPolicy = z.infer<typeof metadataPolicySchema>
1 change: 1 addition & 0 deletions packages/core/src/resolveTrustChains/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './resolveTrustChains'
55 changes: 55 additions & 0 deletions packages/core/src/resolveTrustChains/resolveTrustChains.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// * Fetch the entity configurations, until the trust anchors are hit
// * Fetch the entity statements back until the entityId is hit
// * Merge and apply the policies, trickeling down
// * Return a list of trust chains where the policies are applied, ending up at the `entityId` again
// * Errors
// * when no trust anchor could be found
// * when no trust chain with valid applied could be found
// resolveTrustChains(entityId: string, trustAnchorEntityIds: Array<string>) -> Promise<Array<TrustChain>>

import { fetchEntityConfigurationChains } from '../entityConfiguration'
import { fetchEntityStatementChain } from '../entityStatement'
import type { VerifyCallback } from '../utils'

type Options = {
verifyJwtCallback: VerifyCallback
entityId: string
trustAnchorEntityIds: Array<string>
}

type TrustChain = Awaited<ReturnType<typeof fetchEntityStatementChain>>

// TODO: Apply the policies

export const resolveTrustChains = async (options: Options): Promise<Array<TrustChain>> => {
const { entityId, trustAnchorEntityIds, verifyJwtCallback } = options

const now = new Date()

const entityConfigurationChains = await fetchEntityConfigurationChains({
leafEntityId: entityId,
trustAnchorEntityIds,
verifyJwtCallback,
})

const trustChains: Array<TrustChain> = []

for (const chain of entityConfigurationChains) {
// The last item in the chain is the trust anchor's entity configuration
const entityStatementChain = await fetchEntityStatementChain({
entityConfigurations: chain,
verifyJwtCallback,
})

if (entityStatementChain.some((statement) => statement.exp < now)) {
// Skip expired chains
continue
}

// TODO: Merge all the policies and check them against the metadata of the leaf entity

trustChains.push(entityStatementChain)
}

return trustChains
}
Loading

0 comments on commit 6c8bc37

Please sign in to comment.