-
Notifications
You must be signed in to change notification settings - Fork 55
Description
Prerequisites
- Write a descriptive title.
- Make sure you are able to repro it on the latest version
- Search the existing issues.
Summary
I noticed initially that the JSON Schema returned for the Microsoft.DSC.Debug/Echo resource seemed strange, particularly the last entry in the anyOf keyword, which is just true.
Schema for the Echo resource
$schema: https://json-schema.org/draft/2020-12/schema
title: Echo
type: object
properties:
output:
$ref: '#/$defs/Output'
showSecrets:
type:
- boolean
- 'null'
additionalProperties: false
required:
- output
$defs:
Output:
anyOf:
- type: array
items: true
- type: boolean
- type: integer
format: int64
- $ref: '#/$defs/SecureObject'
- $ref: '#/$defs/SecureString'
- type: string
- true
SecureObject:
type: object
properties:
secureObject: true
additionalProperties: false
required:
- secureObject
SecureString:
type: object
properties:
secureString:
type: string
additionalProperties: false
required:
- secureStringThis relates back to how the type is defined:
DSC/resources/dscecho/src/echo.rs
Lines 8 to 26 in 726a323
| #[derive(Debug, Clone, PartialEq, Deserialize, Serialize, JsonSchema)] | |
| #[serde(untagged)] | |
| pub enum Output { | |
| #[serde(rename = "array")] | |
| Array(Vec<Value>), | |
| #[serde(rename = "bool")] | |
| Bool(bool), | |
| #[serde(rename = "number")] | |
| Number(i64), | |
| #[serde(rename = "secureObject")] | |
| SecureObject(SecureObject), | |
| #[serde(rename = "secureString")] | |
| SecureString(SecureString), | |
| #[serde(rename = "string")] | |
| String(String), | |
| // Object has to be last so it doesn't get matched first | |
| #[serde(rename = "object")] | |
| Object(Value), | |
| } |
Where line 25 defines the Object variant as taking a type of Value, which schemars generates as true. This effectively means that any value is always valid and negates the other entries in the anyOf keyword, but makes parsing the type more confusing.
Analysis
More correctly, Object should be of type Map<String, Value>, which is what the serde_json::Value::as_object() function returns when a Value instance is a JSON object.
Then the generated schema would be an object. This still has some wriggly complications for the actual schema, because validation more correctly only cares about when secureObject or secureString are defined at the top-level of the instance.
In other words, DSC today validates the following instance with the generated schema:
output:
secureString: 'my secret' # `secureString` is a string
secureObject: # `secureObject` is an object
count: 5
name: foo
insecureObject:
secureString: 5 # `insecureObject.secureString` is an integer
secureObject: foo # `insecureObject.secureObject` is a stringAs Object because it wasn't any of the prior items.
Fix proposal
I think the easiest fix is to make Object wrap Map<String, Value> instead of Value. However, it's not obvious based on the generated schema that secureString and secureObject as nested properties or array items are also subject to redaction.
To handle that, we probably need to do a more resilient schema definition which is unlikely to be readily generatable from schemars.
Steps to reproduce
dsc schema -r Microsoft.DSC.Debug/EchoExpected behavior
Schema from dsc resource schema command
$schema: https://json-schema.org/draft/2020-12/schema
title: Echo
type: object
properties:
output:
$ref: '#/$defs/Output'
showSecrets:
type:
- boolean
- 'null'
additionalProperties: false
required:
- output
$defs:
Output:
anyOf:
- type: array
items: true
- type: boolean
- type: integer
format: int64
- $ref: '#/$defs/SecureObject'
- $ref: '#/$defs/SecureString'
- type: string
- type: object
allOf:
- not:
required: [secureObject]
- not:
required: [secureString]
SecureObject:
type: object
properties:
secureObject: true
additionalProperties: false
required:
- secureObject
SecureString:
type: object
properties:
secureString:
type: string
additionalProperties: false
required:
- secureStringActual behavior
Schema from dsc resource schema command
$schema: https://json-schema.org/draft/2020-12/schema
title: Echo
type: object
properties:
output:
$ref: '#/$defs/Output'
showSecrets:
type:
- boolean
- 'null'
additionalProperties: false
required:
- output
$defs:
Output:
anyOf:
- type: array
items: true
- type: boolean
- type: integer
format: int64
- $ref: '#/$defs/SecureObject'
- $ref: '#/$defs/SecureString'
- type: string
- true
SecureObject:
type: object
properties:
secureObject: true
additionalProperties: false
required:
- secureObject
SecureString:
type: object
properties:
secureString:
type: string
additionalProperties: false
required:
- secureStringError details
N/A
Environment data
Name Value
---- -----
PSVersion 7.5.3
PSEdition Core
GitCommitId 7.5.3
OS Microsoft Windows 10.0.26200
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0Version
Latest main
Visuals
No response