Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Environment Variables in definition #33

Open
Download opened this issue Aug 31, 2017 · 8 comments
Open

Environment Variables in definition #33

Download opened this issue Aug 31, 2017 · 8 comments

Comments

@Download
Copy link

Sorry if this came up before, I searched but could not find anything.

Environment variables have become something of the de facto mechanism to set server-specific values, then access them from software. The hosting providers I have worked with (AWS, Heroku, OpenShift) all offer features to easily set/import/export them and most software I've seen meant to run on these systems uses it for things like environment specific URLs, secrets etc.

But afaik there is no way to reference environment variables in an OpenAPI definition.

Would this be a feature to support? I imagine the definition having a section (probably at the top level) that specified a set of environment variables expected to be set, and possibly the default values to use when they are not set. Those variables could then be used in other parts of the definition.

My practical use cases comes from needing to set different authorization urls for different environments. Currently I am rendering swagger.json from JSP to implement this myself, but it seems to me this is a very generic use case that many people will face.

See also e.g.
OAI/OpenAPI-Specification#169
OAI/OpenAPI-Specification#779
swagger-api/swagger-ui#3410

@darrelmiller
Copy link
Member

@Download There is no reason that tooling could not use environment variables to drive ServerVariables that are used for constructing the base URL of the API.

However, I don't know whether we would want to enable arbitrary variables through the spec that would need to be resolved from the environment before the spec is processable. What are the limits? Can an environment variable be used to define part of the path of a path item key? Can an environment variable be used to provide values to Schema properties? Does this introduce a pre-processing stop for resolving variables before being able to validate the spec?

@Download
Copy link
Author

Download commented Sep 9, 2017

Yeah I see your issue. Where does it stop? Personally I would want this feature to be able to change some URL's, like for the oauth server. I used to have a static swagger.json file, but had to turn it into a dynamically served file to be able to change the URL.

A whole different approach might be to have a setup with profiles for different situations, where you could specify e.g. multiple auth configs and select one.

I understand it's a complex issue. Maybe the spec isn't the right place for it and it should be moved to the tooling itself.

@kscheirer
Copy link

I am looking at if/how overlays can solve this problem as part of determining whether overlay spec is sufficient. I won't comment on other solutions now.

An example overlay to update servers and auth urls, assuming authentication like this example is in contract - https://swagger.io/docs/specification/authentication/. You could also give the whole securityScheme object instead.

{
  "overlay": "1.0.0",
  "info": {
    "title": "Servers and Authentication Overlay",
    "version": "1.0.0"
  },
  "actions": [
    {
      "target": "info",
      "update": {
        "x-overlay-applied": "common-servers-auth"
      }
    },
    {
      "description": "Add default servers",
      "target": "@",
      "update": {
        "servers": [
          {
            "description": "Sandbox",
            "url": "http://sandbox.petstore.swagger.io"
          },
          {
            "description": "Prod",
            "url": "http://petstore.swagger.io"
          }
        ]
      }
    },
    {
      "description": "Add auth urls",
      "target": "components.securitySchemes.OAuth2.flows.authorizationCode",
      "update": {
        "authorization_url": "https://example.com/oauth/authorize",
        "token_url": "https://example.com/oauth/token"
      }
    }
  ]
}

@MarttiR
Copy link

MarttiR commented Mar 30, 2023

This really needs to be supported.

One workaround is to create files in build tooling just to store each single environment variable needed for the spec. Those can then be $ref'd, but:

  • the build process is now coupled with the runtime application
  • this obviously violates 12-factor-app config rule
  • the files are baked in to container images at build time, which makes them specific to environments – this multiplies image build and storage costs!

Another workaround would be to manually run envsubst, or lacking that, sed -i all the spec files for all the needed envvars in a preprocess step. This implies some extra tooling around the OpenAPI build, as it would now use the preprocessed files instead of the source files.

Please consider supporting e.g. "some-string-prefix-${ENVVAR_NAME}-and-suffix" interpolation to make reinventing the wheel unnecessary.

@MikeRalphson
Copy link
Member

Please consider supporting e.g. "some-string-prefix-${ENVVAR_NAME}-and-suffix" interpolation to make reinventing the wheel unnecessary.

RFC6570 states

The expression syntax specifically excludes use of the dollar ("$")
and parentheses ["(" and ")"] characters so that they remain
available for use outside the scope of this specification. For
example, a macro language might use these characters to apply macro
substitution to a string prior to that string being processed as a
URI Template.

so I see no reason why tooling could not make use of this ($(ENV_VAR)) convention, but I'm unsure whether it needs to be called out in the specification itself...

@MarttiR
Copy link

MarttiR commented Mar 30, 2023

RFC6570 states

The expression syntax specifically excludes use of the dollar ("$")
and parentheses ["(" and ")"] characters so that they remain
available for use outside the scope of this specification.

Alright, that's a very good reason not to do it. Thanks!

@MikeRalphson
Copy link
Member

Alright, that's a very good reason not to do it. Thanks!

No, I'm saying you can do it (today) with $(..) not ${...} but as you need a tool to do the replacement, it feels more like a tooling issue than something we need to put in the spec. We could add it to our documentation as a 'best practice'?

@handrews handrews transferred this issue from OAI/OpenAPI-Specification Apr 18, 2024
@lornajane
Copy link
Contributor

Thanks for transferring this @handrews. I think overlays is a good way to update server variables, but I am still unclear if we need to adopt the environment variable substitution step into the formal description, or just document a recommended workflow. Comments welcome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants