Skip to content

Disallow fragments in uri-references that point elsewhere in the OpenAPI description #4423

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

Conversation

karenetheridge
Copy link
Member

As referenced in #4389

Tick one of the following options:

  • schema changes are included in this pull request
  • schema changes are needed for this pull request but not done yet
  • no schema changes are needed for this pull request

Copy link
Member

@handrews handrews left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The definition is fine, but AFAICT the only place where it would be used would be the new $self field. I thought there were more but I can't think of any now.

@@ -621,8 +619,7 @@ $defs:
type: object
properties:
operationRef:
type: string
format: uri-reference
$ref: '#/$defs/uri-reference-no-fragment'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

operationRef is allowed to (and in fact almost always does) have a fragment.

@@ -214,8 +213,7 @@ $defs:
type: object
properties:
$ref:
type: string
format: uri-reference
$ref: '#/$defs/uri-reference-no-fragment'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of the $ref fields are allowed to have a fragment.

@@ -716,8 +713,7 @@ $defs:
type: object
properties:
$ref:
type: string
format: uri-reference
$ref: '#/$defs/uri-reference-no-fragment'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of the $ref fields are allowed to have a fragment.

@@ -11,8 +11,7 @@ properties:
info:
$ref: '#/$defs/info'
jsonSchemaDialect:
type: string
format: uri-reference
$ref: '#/$defs/uri-reference-no-fragment'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As with $schema, a fragment is allowed. It is not particularly good practice, and if matching a $id there are limits on what fragment, but $schema (and therefore jsonSchemaDialect) is not restricted to only targeting $id values.

@miqui
Copy link
Contributor

miqui commented Mar 9, 2025

finally got all caught up: proposal-->pr 4389. @karenetheridge , @rahulsom are we missing anything?

@karenetheridge
Copy link
Member Author

Looking again.. I think I was on autopilot when I wrote this ;)

@karenetheridge karenetheridge force-pushed the ether/uri-reference-no-fragment branch from 9cf8ec8 to 14753e6 Compare March 9, 2025 17:34
@karenetheridge
Copy link
Member Author

Fixed. This only applies (for now) to jsonSchemaDialect, as a metaschema cannot be embedded inside another document e.g. as a definition.

@handrews
Copy link
Member

handrews commented Mar 9, 2025

@karenetheridge

a metaschema cannot be embedded inside another document e.g. as a definition.

Can you provide a citation for this? §8.1.1 The "$schema" keyword states:

The "$schema" keyword is both used as a JSON Schema dialect identifier and as the identifier of a resource which is itself a JSON Schema, which describes the set of valid schemas written for this particular dialect.

The value of this keyword MUST be a URI [RFC3986] (containing a scheme) and this URI MUST be normalized. The current schema MUST be valid against the meta-schema identified by this URI.

If this URI identifies a retrievable resource, that resource SHOULD be of media type "application/schema+json".

It goes on to forbid using $schema in a non-resource-root, but I don't see anything forbidding it from pointing to such a schema.

The "$schema" keyword SHOULD be used in the document root schema object, and MAY be used in the root schema objects of embedded schema resources. It MUST NOT appear in non-resource root schema objects. If absent from the document root schema, the resulting behavior is implementation-defined.

(honestly I'm a bit surprised, as I also thought it was forbidden, but I can't find any requirement forbidding it?)

@karenetheridge karenetheridge force-pushed the ether/uri-reference-no-fragment branch from 14753e6 to 307e9bc Compare March 9, 2025 18:20
This should also apply to $self, when it is added.
@karenetheridge karenetheridge force-pushed the ether/uri-reference-no-fragment branch from 307e9bc to ecd0e3e Compare March 9, 2025 18:20
@karenetheridge
Copy link
Member Author

karenetheridge commented Mar 9, 2025

Ok, a $schema (and $vocabulary) keyword can only exist at a schema resource, which is not necessarily the root.

However, $id must also be present (which is what makes the location a schema resource). $id cannot have a fragment.

Is it legal to refer to a metaschema by a non-canonical identifier (using a json pointer fragment from a higher location)?

I created issue # 1590 in the json-schema-spec repo to get some clarity (and we should really tighten this spec language).

@handrews
Copy link
Member

handrews commented Mar 9, 2025

Ok, a $schema (and $vocabulary) keyword can only exist at a schema resource, which is not necessarily the root.

@karenetheridge what you're talking about here is where $schema is used. This does not impact where it points, AFAICT. I don't see any language that requires the target of $schema to be a schema resource. AFAICT it's legal to say "$schema": "#/$defs/foo". I can't find language that forbids that (which, again, is a surprise to me).

@handrews
Copy link
Member

handrews commented Mar 9, 2025

@karenetheridge I guess part of this is that we typically assume that any metaschema will itself have a $schema. Which of course would be the proper way to do it. And therefore it would have a $id (although I have no answer for you about the non-canonical URI usage). But I also don't see any clear, enforceable requirement that a metaschema use $schema.

@karenetheridge
Copy link
Member Author

what you're talking about here is where $schema is used. This does not impact where it points, AFAICT.

Where it's used has relevance as to what its address is (whether canonical or non-canonical). If it can only be used at a document root, then it would never have a json pointer fragment.

I did find a place in the spec that says that $vocabulary MUST only be at a document root, but not all metaschemas need use $vocabulary.

@handrews
Copy link
Member

handrews commented Mar 9, 2025

@karenetheridge I'm still confused. Yes, $schema MUST be in a resource root (document root or adacent to $id), but this is not relevant to the value of $schema. I cannot find a requirement that forbids this:

$schema: "#/$defs/metaschema"
$defs:
   $ref: "https://json-schema/draft/2020-12"
   unevaluatedProperties: false

Now, this is not that useful since $vocabulary is not transitive (and can only appear in a resource root, and so cannot be added here and preserve the scenario), so technically this would not recognize any non-core keywords. But I can't find anything that says it's invalid. It's just not very useful.

@karenetheridge
Copy link
Member Author

karenetheridge commented Mar 10, 2025

@handrews (leaving aside the missing name for the definition..) I don't think that last example can ever work because the metaschema is contained inside the schema -- and in order to parse the entire document we need to know what the metaschema is first, which hasn't been parsed yet.

@handrews
Copy link
Member

@karenetheridge but what is the requirement that says so? I just don't think we can forbid a syntax without a requirement that forbids it. There are a lot of things in JSON Schema (and the OAS) that don't "work" but aren't forbidden.

@handrews
Copy link
Member

and in order to parse the entire document we need to know what the metaschema is first, which hasn't been parsed yet.

@karenetheridge Actually that is not entirely true. The example only relies on the core vocabulary, which MUST be assumed in order to bootstrap anything. If you take out the unevaluatedProperties keyword, the example would only use the core vocabulary (and be even less useful, but "useful" is not the relevant metric here).

@karenetheridge
Copy link
Member Author

I'm just saying that using an example that cannot mathematically work is not a useful example :)

@handrews
Copy link
Member

@karenetheridge OK in that case jsonSchemaDialect needs to be changed back to format: uri-reference because these are the vaidation schemas and can only fail on outright invalid OADs (not just ones that can't be useful).

@karenetheridge karenetheridge deleted the ether/uri-reference-no-fragment branch March 10, 2025 22:00
@karenetheridge
Copy link
Member Author

There's nothing to do here; the definition can be added to the $self addition if it is relevant there.

@baywet
Copy link
Contributor

baywet commented Mar 13, 2025

@handrews to pick up the relevant pieces from this and follow up with another PR.

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

Successfully merging this pull request may close these issues.

4 participants