@@ -1324,7 +1324,12 @@ <h2 id="scope-usage-">Scope Usage <a name="scope-usage"></a></h2>
13241324 < tr >
13251325 < td > < code class ="language-plaintext highlighter-rouge "> maestro.alerts.writeonly</ code > </ td >
13261326 < td > Write-only access to submit and edit partner alerts.</ td >
1327- < td > POST, PUT</ td >
1327+ < td > POST, PUT (alerts)</ td >
1328+ </ tr >
1329+ < tr >
1330+ < td > < code class ="language-plaintext highlighter-rouge "> maestro.partner.read</ code > </ td >
1331+ < td > Access for partner authorization JWKs</ td >
1332+ < td > </ td >
13281333 </ tr >
13291334 </ tbody >
13301335</ table >
@@ -1718,6 +1723,218 @@ <h4 id="response-3">Response</h4>
17181723</ span > < span class ="p "> }</ span > < span class ="w ">
17191724</ span > </ code > </ pre > </ div > </ div >
17201725
1726+ < h2 id ="generate-partner-signed-message- "> Generate Partner Signed Message < a name ="generate-partner-signed-message "> </ a > </ h2 >
1727+
1728+ < p > Generate signed message tokens for partner offer authorization. This endpoint prevents unauthorized access to partner offers by validating user context and minting short-lived signed tokens with RS256 signature.</ p >
1729+
1730+ < h3 id ="scopes-2 "> Scopes</ h3 >
1731+
1732+ < p > < code class ="language-plaintext highlighter-rouge "> maestro.partner.readwrite</ code > - Refer to < a href ="#scope-usage "> Scope Usage</ a > for full details.</ p >
1733+
1734+ < h3 id ="request-4 "> Request</ h3 >
1735+
1736+ < h4 id ="uri-2 "> URI</ h4 >
1737+
1738+ < h5 id ="template-2 "> Template</ h5 >
1739+
1740+ < div class ="language-shell highlighter-rouge "> < div class ="highlight "> < pre class ="highlight "> < code > POST /maestro/v4/partner/signed-message?tripId< span class ="o "> ={</ span > tripId< span class ="o "> }</ span >
1741+ </ code > </ pre > </ div > </ div >
1742+
1743+ < h5 id ="parameters-2 "> Parameters</ h5 >
1744+
1745+ < table >
1746+ < thead >
1747+ < tr >
1748+ < th > Name</ th >
1749+ < th > Type</ th >
1750+ < th > Description</ th >
1751+ </ tr >
1752+ </ thead >
1753+ < tbody >
1754+ < tr >
1755+ < td > < code class ="language-plaintext highlighter-rouge "> tripId</ code > </ td >
1756+ < td > < code class ="language-plaintext highlighter-rouge "> string</ code > </ td >
1757+ < td > < strong > Required</ strong > Concur Trip ID for context validation</ td >
1758+ </ tr >
1759+ < tr >
1760+ < td > < code class ="language-plaintext highlighter-rouge "> Content-Type</ code > </ td >
1761+ < td > < code class ="language-plaintext highlighter-rouge "> string</ code > </ td >
1762+ < td > < strong > Required</ strong > Must be < code class ="language-plaintext highlighter-rouge "> application/json</ code > </ td >
1763+ </ tr >
1764+ < tr >
1765+ < td > < code class ="language-plaintext highlighter-rouge "> Authorization</ code > </ td >
1766+ < td > < code class ="language-plaintext highlighter-rouge "> string</ code > </ td >
1767+ < td > < strong > Required</ strong > Bearer User JWT Token</ td >
1768+ </ tr >
1769+ </ tbody >
1770+ </ table >
1771+
1772+ < h4 id ="headers-4 "> Headers</ h4 >
1773+
1774+ < ul >
1775+ < li > < a href ="https://tools.ietf.org/html/rfc7231#section-5.3.2 "> RFC 7231 Accept</ a > </ li >
1776+ < li > < a href ="https://tools.ietf.org/html/rfc7231#section-3.1.1.5 "> RFC 7231 Content-Type</ a > </ li >
1777+ < li > < a href ="https://tools.ietf.org/html/rfc7235#section-4.2 "> RFC 7235 Authorization</ a > </ li >
1778+ </ ul >
1779+
1780+ < h3 id ="response-4 "> Response</ h3 >
1781+
1782+ < h4 id ="status-codes-2 "> Status Codes</ h4 >
1783+
1784+ < ul >
1785+ < li > < a href ="https://tools.ietf.org/html/rfc7231#section-6.3.1 "> 200 OK</ a > - Signed message generated successfully</ li >
1786+ < li > < a href ="https://tools.ietf.org/html/rfc7231#section-6.5.1 "> 400 Bad Request</ a > - Invalid or missing parameters</ li >
1787+ < li > < a href ="https://tools.ietf.org/html/rfc7235#section-3.1 "> 401 Unauthorized</ a > - User JWT validation failed</ li >
1788+ < li > < a href ="https://tools.ietf.org/html/rfc7231#section-6.5.3 "> 403 Forbidden</ a > - Valid user JWT but user not entitled to offer</ li >
1789+ < li > < a href ="https://tools.ietf.org/html/rfc7231#section-6.6.1 "> 500 Internal Server Error</ a > - Message generation failed</ li >
1790+ </ ul >
1791+
1792+ < h4 id ="headers-5 "> Headers</ h4 >
1793+
1794+ < ul >
1795+ < li > < code class ="language-plaintext highlighter-rouge "> concur-correlationid</ code > is a Concur specific custom header used for technical support in the form of a < a href ="https://tools.ietf.org/html/rfc4122 "> RFC 4122 A Universally Unique IDentifier (UUID) URN Namespace</ a > </ li >
1796+ < li > < a href ="https://tools.ietf.org/html/rfc7230#section-3.3.2 "> RFC 7230 Content-Length</ a > </ li >
1797+ < li > < a href ="https://tools.ietf.org/html/rfc7231#section-3.1.1.5 "> RFC 7231 Content-Type</ a > </ li >
1798+ < li > < a href ="https://tools.ietf.org/html/rfc7231#section-7.1.1.2 "> RFC 7231 Date</ a > </ li >
1799+ < li > < a href ="https://tools.ietf.org/html/rfc7234#section-5.2 "> RFC 7234 Cache-Control</ a > </ li >
1800+ </ ul >
1801+
1802+ < h4 id ="payload-4 "> Payload</ h4 >
1803+
1804+ < ul >
1805+ < li > < a href ="#schema-partner-signed-message-response "> Partner Signed Message Response</ a > </ li >
1806+ < li > < a href ="#schema-error-message "> Error Message</ a > </ li >
1807+ </ ul >
1808+
1809+ < h3 id ="example-2 "> Example</ h3 >
1810+
1811+ < h4 id ="request-5 "> Request</ h4 >
1812+
1813+ < div class ="language-shell highlighter-rouge "> < div class ="highlight "> < pre class ="highlight "> < code > POST https://us.api.concursolutions.com/maestro/v4/partner/signed-message?tripId< span class ="o "> =</ span > trip-uuid-456
1814+ Accept: application/json
1815+ Content-Type: application/json
1816+ Authorization: Bearer < span class ="o "> {</ span > user-jwt-token< span class ="o "> }</ span >
1817+ </ code > </ pre > </ div > </ div >
1818+
1819+ < h4 id ="response-5 "> Response</ h4 >
1820+
1821+ < div class ="language-shell highlighter-rouge "> < div class ="highlight "> < pre class ="highlight "> < code > HTTP/1.1 200
1822+ concur-correlationid: 5512c7be-3fab-4d65-ae69-8a74a04a0c7f
1823+ content-length: 450
1824+ content-type: application/json< span class ="p "> ;</ span > < span class ="nv "> charset</ span > < span class ="o "> =</ span > UTF-8
1825+ < span class ="nb "> date</ span > : Wed, 08 Jul 2020 03:00:42 GMT
1826+ cache-control: no-cache, private
1827+ </ code > </ pre > </ div > </ div >
1828+
1829+ < div class ="language-json highlighter-rouge "> < div class ="highlight "> < pre class ="highlight "> < code > < span class ="p "> {</ span > < span class ="w ">
1830+ </ span > < span class ="nl "> "signedMessage"</ span > < span class ="p "> :</ span > < span class ="w "> </ span > < span class ="s2 "> "eyJhbGciOiJSUzI1NiIsImtpZCI6ImNvbmN1ci1rZXktMSJ9.eyJpc3MiOiJjb25jdXJzb2x1dGlvbnMuY29tIiwiYXVkIjoiZ3JvdW5kc3Bhbi5jb20iLCJpYXQiOjE2NDI3ODU2MDAsImV4cCI6MTY0Mjc4NTcyMCwianRpIjoidXVpZC0xMjM0IiwidXNlcklkIjoiMTcxYTY2MDctYzk0ZS00MGE3LWE3YzktZGFjMDI5OGMyODE3IiwidHJpcElkIjoidHJpcC11dWlkLTQ1NiJ9..."</ span > < span class ="w ">
1831+ </ span > < span class ="p "> }</ span > < span class ="w ">
1832+ </ span > </ code > </ pre > </ div > </ div >
1833+
1834+ < h2 id ="retrieve-public-keys-jwks- "> Retrieve Public Keys (JWKS) < a name ="retrieve-public-keys "> </ a > </ h2 >
1835+
1836+ < p > Authenticated endpoint for partners to retrieve Concur’s public keys for validating signed message tokens. Requires company JWT authentication to ensure only authorized partners can access public key information.</ p >
1837+
1838+ < h3 id ="scopes-3 "> Scopes</ h3 >
1839+
1840+ < p > < code class ="language-plaintext highlighter-rouge "> maestro.partner.readwrite</ code > - Refer to < a href ="#scope-usage "> Scope Usage</ a > for full details.</ p >
1841+
1842+ < h3 id ="request-6 "> Request</ h3 >
1843+
1844+ < h4 id ="uri-3 "> URI</ h4 >
1845+
1846+ < h5 id ="template-3 "> Template</ h5 >
1847+
1848+ < div class ="language-shell highlighter-rouge "> < div class ="highlight "> < pre class ="highlight "> < code > GET /maestro/v4/jwks
1849+ </ code > </ pre > </ div > </ div >
1850+
1851+ < h5 id ="parameters-3 "> Parameters</ h5 >
1852+
1853+ < table >
1854+ < thead >
1855+ < tr >
1856+ < th > Name</ th >
1857+ < th > Type</ th >
1858+ < th > Description</ th >
1859+ </ tr >
1860+ </ thead >
1861+ < tbody >
1862+ < tr >
1863+ < td > < code class ="language-plaintext highlighter-rouge "> Authorization</ code > </ td >
1864+ < td > < code class ="language-plaintext highlighter-rouge "> string</ code > </ td >
1865+ < td > < strong > Required</ strong > Bearer Company JWT Token</ td >
1866+ </ tr >
1867+ </ tbody >
1868+ </ table >
1869+
1870+ < h4 id ="headers-6 "> Headers</ h4 >
1871+
1872+ < ul >
1873+ < li > < a href ="https://tools.ietf.org/html/rfc7231#section-5.3.2 "> RFC 7231 Accept</ a > </ li >
1874+ < li > < a href ="https://tools.ietf.org/html/rfc7235#section-4.2 "> RFC 7235 Authorization</ a > </ li >
1875+ </ ul >
1876+
1877+ < h3 id ="response-6 "> Response</ h3 >
1878+
1879+ < h4 id ="status-codes-3 "> Status Codes</ h4 >
1880+
1881+ < ul >
1882+ < li > < a href ="https://tools.ietf.org/html/rfc7231#section-6.3.1 "> 200 OK</ a > - JWKs response with public keys for signature verification</ li >
1883+ < li > < a href ="https://tools.ietf.org/html/rfc7235#section-3.1 "> 401 Unauthorized</ a > - Company JWT validation failed or missing</ li >
1884+ < li > < a href ="https://tools.ietf.org/html/rfc7231#section-6.5.3 "> 403 Forbidden</ a > - Valid company JWT but not authorized for key access</ li >
1885+ < li > < a href ="https://tools.ietf.org/html/rfc7231#section-6.6.1 "> 500 Internal Server Error</ a > - Key retrieval failures</ li >
1886+ </ ul >
1887+
1888+ < h4 id ="headers-7 "> Headers</ h4 >
1889+
1890+ < ul >
1891+ < li > < code class ="language-plaintext highlighter-rouge "> concur-correlationid</ code > is a Concur specific custom header used for technical support in the form of a < a href ="https://tools.ietf.org/html/rfc4122 "> RFC 4122 A Universally Unique IDentifier (UUID) URN Namespace</ a > </ li >
1892+ < li > < a href ="https://tools.ietf.org/html/rfc7230#section-3.3.2 "> RFC 7230 Content-Length</ a > </ li >
1893+ < li > < a href ="https://tools.ietf.org/html/rfc7231#section-3.1.1.5 "> RFC 7231 Content-Type</ a > </ li >
1894+ < li > < a href ="https://tools.ietf.org/html/rfc7231#section-7.1.1.2 "> RFC 7231 Date</ a > </ li >
1895+ < li > < a href ="https://tools.ietf.org/html/rfc7234#section-5.2 "> RFC 7234 Cache-Control</ a > </ li >
1896+ </ ul >
1897+
1898+ < h4 id ="payload-5 "> Payload</ h4 >
1899+
1900+ < ul >
1901+ < li > < a href ="#schema-jwks-response "> JWKS Response</ a > </ li >
1902+ < li > < a href ="#schema-error-message "> Error Message</ a > </ li >
1903+ </ ul >
1904+
1905+ < h3 id ="example-3 "> Example</ h3 >
1906+
1907+ < h4 id ="request-7 "> Request</ h4 >
1908+
1909+ < div class ="language-shell highlighter-rouge "> < div class ="highlight "> < pre class ="highlight "> < code > GET https://us.api.concursolutions.com/maestro/v4/jwks
1910+ Accept: application/json
1911+ Authorization: Bearer < span class ="o "> {</ span > company-jwt-token< span class ="o "> }</ span >
1912+ </ code > </ pre > </ div > </ div >
1913+
1914+ < h4 id ="response-7 "> Response</ h4 >
1915+
1916+ < div class ="language-shell highlighter-rouge "> < div class ="highlight "> < pre class ="highlight "> < code > HTTP/1.1 200
1917+ concur-correlationid: 5512c7be-3fab-4d65-ae69-8a74a04a0c7f
1918+ content-length: 650
1919+ content-type: application/json< span class ="p "> ;</ span > < span class ="nv "> charset</ span > < span class ="o "> =</ span > UTF-8
1920+ < span class ="nb "> date</ span > : Wed, 08 Jul 2020 03:00:42 GMT
1921+ cache-control: no-cache, private
1922+ </ code > </ pre > </ div > </ div >
1923+
1924+ < div class ="language-json highlighter-rouge "> < div class ="highlight "> < pre class ="highlight "> < code > < span class ="p "> {</ span > < span class ="w ">
1925+ </ span > < span class ="nl "> "keys"</ span > < span class ="p "> :</ span > < span class ="w "> </ span > < span class ="p "> [</ span > < span class ="w ">
1926+ </ span > < span class ="p "> {</ span > < span class ="w ">
1927+ </ span > < span class ="nl "> "kty"</ span > < span class ="p "> :</ span > < span class ="w "> </ span > < span class ="s2 "> "RSA"</ span > < span class ="p "> ,</ span > < span class ="w ">
1928+ </ span > < span class ="nl "> "use"</ span > < span class ="p "> :</ span > < span class ="w "> </ span > < span class ="s2 "> "sig"</ span > < span class ="p "> ,</ span > < span class ="w ">
1929+ </ span > < span class ="nl "> "kid"</ span > < span class ="p "> :</ span > < span class ="w "> </ span > < span class ="s2 "> "concur-key-1"</ span > < span class ="p "> ,</ span > < span class ="w ">
1930+ </ span > < span class ="nl "> "n"</ span > < span class ="p "> :</ span > < span class ="w "> </ span > < span class ="s2 "> "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw"</ span > < span class ="p "> ,</ span > < span class ="w ">
1931+ </ span > < span class ="nl "> "e"</ span > < span class ="p "> :</ span > < span class ="w "> </ span > < span class ="s2 "> "AQAB"</ span > < span class ="p "> ,</ span > < span class ="w ">
1932+ </ span > < span class ="nl "> "alg"</ span > < span class ="p "> :</ span > < span class ="w "> </ span > < span class ="s2 "> "RS256"</ span > < span class ="w ">
1933+ </ span > < span class ="p "> }</ span > < span class ="w ">
1934+ </ span > < span class ="p "> ]</ span > < span class ="w ">
1935+ </ span > < span class ="p "> }</ span > < span class ="w ">
1936+ </ span > </ code > </ pre > </ div > </ div >
1937+
17211938< h2 id ="schema- "> Schema < a name ="schema "> </ a > </ h2 >
17221939
17231940< h3 id ="alert-request "> < a name ="schema-alert-request "> </ a > Alert Request</ h3 >
@@ -2116,6 +2333,99 @@ <h3 id="error"><a name="schema-error"></a>Error</h3>
21162333 </ tbody >
21172334</ table >
21182335
2336+ < h3 id ="partner-signed-message-response "> < a name ="schema-partner-signed-message-response "> </ a > Partner Signed Message Response</ h3 >
2337+
2338+ < table >
2339+ < thead >
2340+ < tr >
2341+ < th > Name</ th >
2342+ < th > Type</ th >
2343+ < th > Format</ th >
2344+ < th > Description</ th >
2345+ </ tr >
2346+ </ thead >
2347+ < tbody >
2348+ < tr >
2349+ < td > < code class ="language-plaintext highlighter-rouge "> signedMessage</ code > </ td >
2350+ < td > < code class ="language-plaintext highlighter-rouge "> string</ code > </ td >
2351+ < td > -</ td >
2352+ < td > < strong > Required</ strong > RS256-signed JWT token containing user and trip context</ td >
2353+ </ tr >
2354+ </ tbody >
2355+ </ table >
2356+
2357+ < h3 id ="jwks-response "> < a name ="schema-jwks-response "> </ a > JWKS Response</ h3 >
2358+
2359+ < table >
2360+ < thead >
2361+ < tr >
2362+ < th > Name</ th >
2363+ < th > Type</ th >
2364+ < th > Format</ th >
2365+ < th > Description</ th >
2366+ </ tr >
2367+ </ thead >
2368+ < tbody >
2369+ < tr >
2370+ < td > < code class ="language-plaintext highlighter-rouge "> keys</ code > </ td >
2371+ < td > < code class ="language-plaintext highlighter-rouge "> array</ code > </ td >
2372+ < td > < a href ="#schema-jwk "> < code class ="language-plaintext highlighter-rouge "> JWK</ code > </ a > </ td >
2373+ < td > < strong > Required</ strong > Array of JSON Web Keys for signature verification</ td >
2374+ </ tr >
2375+ </ tbody >
2376+ </ table >
2377+
2378+ < h3 id ="jwk-json-web-key "> < a name ="schema-jwk "> </ a > JWK (JSON Web Key)</ h3 >
2379+
2380+ < table >
2381+ < thead >
2382+ < tr >
2383+ < th > Name</ th >
2384+ < th > Type</ th >
2385+ < th > Format</ th >
2386+ < th > Description</ th >
2387+ </ tr >
2388+ </ thead >
2389+ < tbody >
2390+ < tr >
2391+ < td > < code class ="language-plaintext highlighter-rouge "> kty</ code > </ td >
2392+ < td > < code class ="language-plaintext highlighter-rouge "> string</ code > </ td >
2393+ < td > -</ td >
2394+ < td > < strong > Required</ strong > Key type (RSA)</ td >
2395+ </ tr >
2396+ < tr >
2397+ < td > < code class ="language-plaintext highlighter-rouge "> use</ code > </ td >
2398+ < td > < code class ="language-plaintext highlighter-rouge "> string</ code > </ td >
2399+ < td > -</ td >
2400+ < td > < strong > Required</ strong > Key usage (sig for signature)</ td >
2401+ </ tr >
2402+ < tr >
2403+ < td > < code class ="language-plaintext highlighter-rouge "> kid</ code > </ td >
2404+ < td > < code class ="language-plaintext highlighter-rouge "> string</ code > </ td >
2405+ < td > -</ td >
2406+ < td > < strong > Required</ strong > Key identifier for rotation support</ td >
2407+ </ tr >
2408+ < tr >
2409+ < td > < code class ="language-plaintext highlighter-rouge "> n</ code > </ td >
2410+ < td > < code class ="language-plaintext highlighter-rouge "> string</ code > </ td >
2411+ < td > -</ td >
2412+ < td > < strong > Required</ strong > RSA public key modulus</ td >
2413+ </ tr >
2414+ < tr >
2415+ < td > < code class ="language-plaintext highlighter-rouge "> e</ code > </ td >
2416+ < td > < code class ="language-plaintext highlighter-rouge "> string</ code > </ td >
2417+ < td > -</ td >
2418+ < td > < strong > Required</ strong > RSA public key exponent</ td >
2419+ </ tr >
2420+ < tr >
2421+ < td > < code class ="language-plaintext highlighter-rouge "> alg</ code > </ td >
2422+ < td > < code class ="language-plaintext highlighter-rouge "> string</ code > </ td >
2423+ < td > -</ td >
2424+ < td > < strong > Required</ strong > Algorithm (RS256)</ td >
2425+ </ tr >
2426+ </ tbody >
2427+ </ table >
2428+
21192429 </ div >
21202430 <!--/col-md-8-->
21212431
0 commit comments