Having difficulties overriding securedBy in an extension


#1

I might be replicating this post too much, on GitHub issues, Slack, and here, but just thought this post could be also appropriate here in forum.

I want to override securedBy node of a method in an extension, but having a hard time making it work as expected. The simplified version of the specs are like below.

First case

#%RAML 1.0
title: Public API
baseUri: https://example.com/v1
securitySchemes:
  oauth: !include securitySchemes/oauth.raml
/users:
  get:
    securedBy: [oauth]

#%RAML 1.0
title: Private API
baseUri: https://example.com/v1/internal
securitySchemes:
  adminKey: !include securitySchemes/admin_key.raml
/users:
  get:
    securedBy: [adminKey]

It is basically providing additional security scheme for private internal users. What I expect for the /users endpoint of Private API is to have two security schema applications, oauth, and admin_key. However, I am just getting one security scheme adminKey for Private API.

If I declare two security schemes in Private API like below, I get three security schemes [oauth, adminKey, oauth], which neither is what I want.

Second case

#%RAML 1.0
title: Private API
baseUri: https://example.com/v1/internal
securitySchemes:
  adminKey: !include securitySchemes/admin_key.raml
/users:
  get:
    securedBy: [oauth, adminKey]

According to the spec in RAML 1.0 Spec, security schema applications are considered simple properties in merging rules.

Security Schema applications are always Simple Properties.

What I guess is that:

  • The first case regards securedBy as a single-value simple property, which is just replaced with the value in extension Private API.
  • The second case regards securedBy as a multi-value simple property, which concatenates these values to produce [oauth, adminKey, oauth] combination.

Merging rule for simple properties are also stated in RAML 1.0 Spec.

  • If the property is a Simple Property
    • If the property is a Single-value Simple Property,
      • The property value in the identically named Current Target Tree Object property is replaced with its value from Current Extension Tree Object property.
    • If the property is a Multi-value Simple Property
      • The property value from Current Extension Tree Object property is added to the identically named Current Target Tree Object property values if no such value already exists.

Final question

Looking at above specs, the parsed results seem to correspond with the spec. My final question is this. What would be the best way to apply an additional security scheme to an endpoint in extension? Thanks for your help in advance :slight_smile:


#2

Let me try to disambiguate. In RAML 1.0’s Overlay/Extension merging mechanism, Array properties get either:

  • merged: [a] (extended RAML) + [b] (overlay/extension) = [a, b]
  • merged and deduplicated if the property exist: [a] + [a, b] = [a, b]
  • created if the Array doesn’t exist in the extended RAML: + [a] = [a]

So in your case, you’ll want to have three files:

  • a main RAML file without security scheme
  • an extension for your public API with oauth security scheme
  • an extension for your private API with adminKey security scheme

E.g.

api.raml

#%RAML 1.0
title: API
/users:
  get:

public-api.raml:

#%RAML 1.0 Extension
extends: api.raml
title: Public API
baseUri: https://example.com/v1
securitySchemes:
  oauth: !include securitySchemes/oauth.raml
/users:
  get:
    securedBy: [oauth]

private-api.raml:

#%RAML 1.0 Extension
extends: api.raml
title: Private API
baseUri: https://private/v1
securitySchemes:
  adminKey: !include securitySchemes/admin_key.raml
/users:
  get:
    securedBy: [adminKey]

#3

Thanks for your response! I have been waiting for it :slight_smile:

Actually, the behavior I expect is the first and second case of the merging algorithms you mentioned, which are:

  • merged : [a] (extended RAML) + [b] (overlay/extension) = [a, b]
  • merged and deduplicated if the property exist: [a] + [a, b] = [a, b]

What I am actually getting with the raml js parser are:

  • securedBy: [a] (extension) + securedBy: [b] is producing securedBy: [a]
  • securedBy: [a, b] (extension) + securedBy: [b] is producing securedBy: [a, b, b]

Could this be an issue with the rams js parser? (https://github.com/raml-org/raml-js-parser-2)

I could just go with the solution you provided, using base raml without any security scheme, but if parser implementation is different from the spec, probably this should be addressed :slight_smile:


#4

As far as spec goes, I can confirm this is valid. There will very soon be a new parser which will deprecate the one you are referring to. If it can wait, I would advise to use the new parser instead.


#5

Thanks for your clarification. I would first try to use base raml to separate security scheme applications and wait for the new parser. Is there a link to the new project (assuming it is open-sourced)?