Description: SecKey Procedure vs Oauth2 Token
This article describe the key differences of both authentication methods and why/when it is used when using SAP.
SecKey: History with ArchiveLink
The SecKey-Authentication (See: https://help.sap.com/docs/SAP_NETWEAVER_AS_ABAP_752/3ad3ba0715c5422eae08578d4c40328d/4d007cc099aa1d6ee10000000a42189c.html ) where introduced by SAP a very long time ago when the ArchiveLink-Protocol was created. Back then, there were no fixed concepts of REST (Like OpenAPI etc.) and for sure no concept of authentication other then User/Password (like Oauth2/SAML etc.)
Furthermore, the developer needed to implement a procedure to exchange documents from SAP to an (SAP) Contentserver in a secure way (read, write, delete, update). The Key aspects were:
Exchange the public certificate via HTTP(S) so the Contentserver is able to verify if the origin / signer of the request is in fact the SAP System
Limit permissions (rucd and access time) on specific resources in ArchiveLink
So, the developer at SAP invented two major concepts: the putCert-Request from SAP to an ArchiveLink-conform Archive and a way to create a signed signature which only can be verified by the holder of the public certificate. User/Password authentication was not a valid approach as there is no way to limit the access to specific resources.
Most Important: SAP ArchiveLink does not Support OAuth (or Oauth2)
SecKey: elements and aspects (ArchiveLink)
When accessing a resource on a contentserver, the contentserver needs to be aware of the public certificate from SAP. That way, it can verify the signed message delivered via URL. A typical ArchiveLink-URL for a Request would look like:
http://localhost:8096/KGSAdmin-CSVSBB/contentserver?info&pVersion=0047&contRep=MR&docId=9D7D5D2AC7A34A59AA66AA18A52098E0&compId=data&accessMode=r&authId=CN%3Dkgs-software.com%2COU%3DKGS%2CO%3DAL%2CL%3DFrankfurt%2CST%3DHesse%2CC%3DDE&expiration=20250213122448&secKey=MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAMYIBHjCCARoCAQEwbzBnMQswCQYDVQQGEwJERTEOMAwGA1UECBMFSGVzc2UxEjAQBgNVBAcTCUZyYW5rZnVydDELMAkGA1UEChMCQUwxDDAKBgNVBAsTA0tHUzEZMBcGA1UEAxMQa2dzLXNvZnR3YXJlLmNvbQIEU9EDKDAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMjUwMjEzMTE1NDQ4WjAjBgkqhkiG9w0BCQQxFgQUWx2G7YJZSPpc81WNophx11DIJM0wCQYHKoZIzjgEAwQvMC0CFEbQg3Jf8Cuo2reQAifqLZSw9pWvAhUAiaTiDQwHwFA19VA9lRw2m%2BH%2B5vIAAAAAAAA%3D
the first “info” is the command. (there are many, see https://download.consolut.com/direct/SAP_PrintDoku/en/BCSRVARL/BCSRVARL.PDF ). It define the action that should be performed on that specific document
pVersion is the protocolversion. The ArchiveLink protocol got enhanced multiple times (most of the times just additions). So, common protocol versions are 0045, 0046 and 0047
contRep, docId and compId these three values in combination always identify one (and only one) exact object. Contrep is the repository, the docId the document id (in ArchiveLink, a document can be (simplyfied) seen as a folder) and the compId a component in that folder. An ArchiveLink document can have multiple components. See: https://help.sap.com/docs/ABAP_PLATFORM_NEW/345ce26100fc4ba49fd3dc9b424495c4/4ce65a717e173ec6e10000000a42189b.html
accessMode: Identify which permission is needed to perform the request (as a rucd operation). In that example r = read
authId: Identifier which certificate should be used to verify the secKey.
expiration: the time when the URL is supposed to be invalid. Usually thats current clock-time +2 hours (UTC)
secKey: The most interesting part of all: SAP sign the following parameters “contrep”, “docId”, “compId” ,, “accessMode” and “expiration” with its private Key (on SAP Side). That signature then is Base64 / URLEncoded to transfer via HTTP. The Contentservers task is to look up the public certificate (by the identifier authId) in its certificate store and verify the signed Message (secKey) with the public certificate. While verifying, it also checks, if the values from the URL (contrep, docId, compId, expiration, accessMode) match with the signature in the secKey. If they match, the request shall be granted (but only if the expiration date is not in the past).
CMIS
CMIS (Content Management Interoperability Services) is a Protocol, that was invented to find a standard for exchanging documents and metadata between Content Management Systems. The initial working group consists of the big players in that field (Adobe Systems Incorporated, Alfresco, EMC, FatWire, HP, IBM, Liferay, Microsoft, Nuxeo, OpenText, Oracle, and SAP.)[Source: Content Management Interoperability Services ]. The intention was simple: Get rid of the many different approaches and ways to exchange data and find one protocol that could be used by everyone in that field (in a perfect world). The group identified the key features and defined the protocol in a whitepaper. See: https://docs.oasis-open.org/cmis/CMIS/v1.1/CMIS-v1.1.html
Most of the big players implemented several parts of that whitepaper and there is also a opensource community around it. Everyone agreed that the specification needs to be opensource, therefore, everybody who want to can implement their own CMIS client or Server.
In 2017 there was not much to add to the specification and the working group fell apart. Since then, the Version CMIS 1.1 was the latest version. SAP is using this protocol exensivly for its cloud buisness, as it allows a way more suffisticated approach to handle metadata, authentication, access rules, retentions, renditions and hierachy/inheritance of document structures.
That beeing said, SAP decided to remove the ArchiveLink-Protocol from all Cloud based Systems (only the On-Prem versions still support it) and tried to get rid of ArchiveLink completly, but decades worth of documents and thousands of customers using this protocol make it literally impossible to get rid of it in the forseen future.
CMIS with SecKey
The CMIS Protocol preferes (and should in nearly every scenario) the OAUTH2 Authentication as it is the standard for securing communication (with a bearer token). These tokens get issued by an trusted authority (like Microsoft, AWS etc) when the application have the permission to retrieve a Token. Token usually lives only short-term (like an hour) and get reissued (with a refresh-token-workflow) if needed. That ensures that even if a token is hijacked (e.g by man-in-the-middle) the attacker can only use it for an hour.
The downside of the Token is that you cannot limit this very well on specific objects. Its common to define roles in the token to ensure the token is only used for the intention (for example only read or only write) and its common to use multiple Issuer (in Microsoft they are called “App Registration”) for different repositories. Anyways, if one of those token is phished somehow, the attacker have all permissions for that repository (and the role in the token). This can be prevented by using HTTPS (Microsoft even enforces that a token can only be issued to a client if the client request it via HTTPS). Furthermore, Oauth2 tokens usually comes into the picture in M2M Communication (Machine to Machine) where all Machines are trusted each other (by certificate, TLS).
In the very specific case of SAP, where a user wants to display a document in an external application like the browser, these approach does not work. By opening an external tool, SAP cannot ensure the nature of the browser (customer specific, endclient) and therefore cant trust it. That said, it would be more than critical to expose an Oauth2 token (with the extended permissions) to an unknown user-visible (browser) application. To still be able to display the document to the user in that said browser, SAP choose to combine seckey and oauth2 token.
The Flow is the following: (We skip the part with the putCert)
1.) SAP request a Oauth2 Token via its OAUTH_PROFILE from the trusted Authority (e.g. Microsoft Azure)
2.) SAP retrieve the valid Token
3.) SAP ask in a direct M2M -Request for the Document-Info. In that, the authentication header is filled with “Authentication: bearer <token>”
4.) The Tia Core validate the Token and answer with a valid response (the INFO to the document)
5.) Now, SAP know that the User who triggered the command is allowed to see the document. But to prevent the token-exposure to an external unknown application like a browser, SAP generate a SecKey-URL that is very similar to the ArchiveLink SecKey Procedure and strip the token from the headers. In that Seckey, there are 4 values signed:
the CMIS ObjectID + the Operation (getContentStream) +authID + expirationDate. That is signed into a secKey and opened in the external application (browser).
It looks like that:
https://<server>/browser/rfHN5c3RlbXwxfExTfC8=/root?&ObjectId=dfHN5c3RlbXwxfExTfC9Lbm93bGVkZ2UgUHJvdmlkZXIvQXJjaGl2ZUxpbmsvMUQ3NjMyREZDNDkzMUVERkExOEZDOUVGRTc4ODVFNjgvZGF0YQ%253D%253D&cmisaction=getContentStream&authId=CN%3DKGS%2COU%3DI0020701161%2COU%3DSAPWebAS%2CO%3DSAPTrustCommunity%2CC%3DDE&expiration=20250204123053&secKey=MIIBUgYJKoZIhvcNAQcCoIIBQzCCAT8CAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHATGCAR4wggEaAgEBMHAwZDELMAkGA1UEBhMCREUxHDAaBgNVBAoTE1NBUCBUcnVzdCBDb21tdW5pdHkxEzARBgNVBAsTClNBUCBXZWIgQVMxFDASBgNVBAsTC0kwMDIwNzAzOTYxMQwwCgYDVQQDEwNXNEQCCAogIxAYBzkBMAkGBSsOAwIaBQCgXTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yNTAyMDQwODMwNTNaMCMGCSqGSIb3DQEJBDEWBBS6DdSSIWWgk%2Fn5%2Bf%2Fkemtvkomr7TAJBgcqhkjOOAQDBC4wLAIUBwKjyYwsnjIX2D16enzGJawuDFgCFEuMJ8quhldWMyZsLOvtAOTxhnv7
where:
the /browser/ is the Binding of CMIS
the rfHN5c3RlbXwxfExTfC8= is the BASE64 internal representation of the Repository
the ObjectId is the exact identifier which object should get accessed (hint: the very first letter “d” stands for document)
cmisaction is the allowed action that is performed
authId is the identifier for the public certificate
expiration is the expiration date of the URL (until this URL is valid before it gets declined from the CMIS Server - for some reason different to archivelink: current time (UTC)+ 4 hours)
secKey is the interesting one similar to the ArchiveLink. It also got signed (the four values mentioned above). The CMIS Server then validate the secKey with its public certificate and checks for the expiration date as well. If everything match up, the CMIS Server delivers the document to the browser (where the default PDF-Viewer is handling the Document in case its a PDF. If its not a PDF, the file get offered to download).
Conclusion/Summary:
For every modern communication should Oauth2-Token be used (between two trusted parties - Like M2M etc.). Whenever one chain-element cant be trustet (like a Browser or an enduser-application), a token should not get exposed. Furthermore, TLS (HTTPS) should always be in place.
For the scenarios where a document should get opened in an untrusted application, SAP ensure the access by first checking if the user is allowed to open it by doing a document info first with secKey directly to the CMIS Server and then creating a URL that limit its permissions to exactly that object for a limited amount of time.