@@ -19,17 +19,26 @@ export async function build(): Promise<FastifyInstance> {
1919 } ) ;
2020
2121 // Register schema for request/response validation
22+ const hex = ( bytes : number , description : string ) => ( {
23+ type : 'string' ,
24+ pattern : `^(?:0x[0-9a-fA-F]{0,${ bytes * 2 } }|[0-9a-fA-F]{0,${ bytes * 2 } })$` ,
25+ description,
26+ } ) ;
27+
2228 server . addSchema ( {
2329 $id : 'bootInfo' ,
2430 type : 'object' ,
2531 required : [ 'mrAggregated' , 'osImageHash' , 'appId' , 'composeHash' , 'instanceId' , 'deviceId' ] ,
2632 properties : {
27- mrAggregated : { type : 'string' , description : 'Aggregated MR measurement' } ,
28- osImageHash : { type : 'string' , description : 'OS Image hash' } ,
29- appId : { type : 'string' , description : 'Application ID' } ,
30- composeHash : { type : 'string' , description : 'Compose hash' } ,
31- instanceId : { type : 'string' , description : 'Instance ID' } ,
32- deviceId : { type : 'string' , description : 'Device ID' }
33+ mrAggregated : hex ( 32 , 'Aggregated MR measurement' ) ,
34+ osImageHash : hex ( 32 , 'OS Image hash' ) ,
35+ appId : hex ( 20 , 'Application ID' ) ,
36+ composeHash : hex ( 32 , 'Compose hash' ) ,
37+ instanceId : hex ( 20 , 'Instance ID' ) ,
38+ deviceId : hex ( 32 , 'Device ID' ) ,
39+ tcbStatus : { type : 'string' , maxLength : 128 , default : '' } ,
40+ advisoryIds : { type : 'array' , maxItems : 128 , items : { type : 'string' , maxLength : 256 } , default : [ ] } ,
41+ mrSystem : { ...hex ( 32 , 'System MR measurement' ) , default : '' } ,
3342 }
3443 } ) ;
3544
@@ -50,21 +59,45 @@ export async function build(): Promise<FastifyInstance> {
5059 const provider = new ethers . JsonRpcProvider ( rpcUrl ) ;
5160 server . decorate ( 'ethereum' , new EthereumBackend ( provider , kmsContractAddr ) ) ;
5261
53- server . get ( '/' , async ( request , reply ) => {
54- const batch = await Promise . all ( [
55- server . ethereum . getGatewayAppId ( ) ,
56- server . ethereum . getChainId ( ) ,
57- server . ethereum . getAppImplementation ( ) ,
58- ] ) ;
59- return {
60- status : 'ok' ,
61- kmsContractAddr : kmsContractAddr ,
62- ethRpcUrl : rpcUrl ,
63- gatewayAppId : batch [ 0 ] ,
64- chainId : batch [ 1 ] ,
65- appAuthImplementation : batch [ 2 ] , // NOTE: for backward compatibility
66- appImplementation : batch [ 2 ] ,
67- } ;
62+ const publicRpcEndpoint = ( value : string ) : string => {
63+ try {
64+ const endpoint = new URL ( value ) ;
65+ return `${ endpoint . protocol } //${ endpoint . host } ` ;
66+ } catch {
67+ return 'configured' ;
68+ }
69+ } ;
70+ const backendUnavailable = 'authorization backend unavailable' ;
71+ const invalidRequest = { isAllowed : false , reason : 'invalid authorization request' , gatewayAppId : '' } ;
72+
73+ server . setErrorHandler ( ( error , request , reply ) => {
74+ if ( typeof error === 'object' && error !== null && 'validation' in error ) {
75+ return reply . code ( 400 ) . send ( invalidRequest ) ;
76+ }
77+ request . log . error ( 'authorization request failed' ) ;
78+ return reply . code ( 500 ) . send ( { status : 'error' , message : backendUnavailable } ) ;
79+ } ) ;
80+
81+ server . get ( '/' , async ( _request , reply ) => {
82+ try {
83+ const batch = await Promise . all ( [
84+ server . ethereum . getGatewayAppId ( ) ,
85+ server . ethereum . getChainId ( ) ,
86+ server . ethereum . getAppImplementation ( ) ,
87+ ] ) ;
88+ return {
89+ status : 'ok' ,
90+ kmsContractAddr : kmsContractAddr ,
91+ ethRpcUrl : publicRpcEndpoint ( rpcUrl ) ,
92+ gatewayAppId : batch [ 0 ] ,
93+ chainId : batch [ 1 ] ,
94+ appAuthImplementation : batch [ 2 ] , // NOTE: for backward compatibility
95+ appImplementation : batch [ 2 ] ,
96+ } ;
97+ } catch {
98+ _request . log . error ( 'authorization backend health check failed' ) ;
99+ return reply . code ( 500 ) . send ( { status : 'error' , message : backendUnavailable } ) ;
100+ }
68101 } ) ;
69102
70103 // Define routes
@@ -82,11 +115,11 @@ export async function build(): Promise<FastifyInstance> {
82115 try {
83116 return await server . ethereum . checkBoot ( request . body , false ) ;
84117 } catch ( error ) {
85- console . error ( error ) ;
118+ request . log . error ( 'application authorization backend failed' ) ;
86119 reply . code ( 200 ) . send ( {
87120 isAllowed : false ,
88121 gatewayAppId : '' ,
89- reason : ` ${ error instanceof Error ? error . message : String ( error ) } `
122+ reason : backendUnavailable
90123 } ) ;
91124 }
92125 } ) ;
@@ -106,12 +139,12 @@ export async function build(): Promise<FastifyInstance> {
106139 return await server . ethereum . checkBoot ( request . body , true ) ;
107140 } catch ( error ) {
108141 if ( ! ( error instanceof Error && "Test backend error" == error . message ) ) {
109- console . error ( error ) ;
142+ request . log . error ( 'KMS authorization backend failed' ) ;
110143 }
111144 reply . code ( 200 ) . send ( {
112145 isAllowed : false ,
113146 gatewayAppId : '' ,
114- reason : ` ${ error instanceof Error ? error . message : String ( error ) } `
147+ reason : backendUnavailable
115148 } ) ;
116149 }
117150 } ) ;
0 commit comments