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

fix(certificates): validate the certificates schema failed if snis was in the request body #13357

Merged
merged 1 commit into from
Jul 30, 2024

Conversation

raoxiaoyan
Copy link
Contributor

@raoxiaoyan raoxiaoyan commented Jul 10, 2024

Summary

the endpoint POST /schemas/certificates/validate with entity data:

{
"cert":"",
"key":"",
"snis":["a","b","c"]
}

It throws an error.

{
"code": 2,
"name": "schema violation",
"fields": {
"snis": "unknown field"
},
"message": "schema violation (snis: unknown field)"
}

Currently, the endpoint POST /certificates can batch-create sni entities with snis. But the snis is not part of the certificate schema. so we need to remove it from the request body.

Checklist

  • The Pull Request has tests
  • A changelog file has been created under changelog/unreleased/kong or skip-changelog label added on PR if changelog is unnecessary. README.md
  • [na] There is a user-facing docs PR against https://github.com/Kong/docs.konghq.com - PUT DOCS PR HERE

Issue reference

KM-223

@github-actions github-actions bot added core/admin-api cherry-pick kong-ee schedule this PR for cherry-picking to kong/kong-ee labels Jul 10, 2024
@raoxiaoyan raoxiaoyan added this to the 3.8.0 milestone Jul 10, 2024
Copy link
Contributor

@liverpool8056 liverpool8056 left a comment

Choose a reason for hiding this comment

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

From my perspective it would be better to keep consistent logic between real creation of certificates entity and validation of entity rather than simply removing sni field. To do this, we can refer to/reuse the same validation logics which are adopted in the dao/certificates and dao/sni

The necessity I think is to ensure that entity which is proved to be valid by endpoint /validate can be accepted by the upcoming post method.

@raoxiaoyan
Copy link
Contributor Author

raoxiaoyan commented Jul 10, 2024

From my perspective it would be better to keep consistent logic between real creation of certificates entity and validation of entity rather than simply removing sni field. To do this, we can refer to/reuse the same validation logics which are adopted in the dao/certificates and dao/sni

The necessity I think is to ensure that entity which is proved to be valid by endpoint /validate can be accepted by the upcoming post method.

Nice.
For my understanding. I think the endpoint /schema/:dn_entity_name/validate is the most important to validate the fields that belong to the schema. Second, to validate the field value if it is valid.

@liverpool8056
Copy link
Contributor

For my understanding. I think the endpoint /schema/:dn_entity_name/validate is the most important to validate the fields that belong to the schema. Second, to validate the field value if it is valid.

To this extent, the /validate endpoint just carry out some preliminary validations, which also makes sense.

Copy link
Member

@sumimakito sumimakito left a comment

Choose a reason for hiding this comment

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

LGTM

changelog/unreleased/kong/certificates_schema_validate.yml Outdated Show resolved Hide resolved
kong/api/routes/kong.lua Outdated Show resolved Hide resolved
@AndyZhang0707
Copy link
Collaborator

Convert to draft for now as it requires more design discussion.

@raoxiaoyan raoxiaoyan marked this pull request as ready for review July 15, 2024 09:39
Copy link
Member

@sumimakito sumimakito left a comment

Choose a reason for hiding this comment

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

Code LGTM. Let's have someone from the Gateway team review the code as well

kong/db/schema/metaschema.lua Show resolved Hide resolved
Copy link
Contributor

@nowNick nowNick left a comment

Choose a reason for hiding this comment

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

I'm wondering whether transient is the best name here 🤔 . What I think we're trying to achieve is adding a field to schema that's actually the reverse of type = "foreign" what sometimes is called backref.

transient sounds to me like a field that could be derived from other fields. For example we'd have somewhere a network address field which values would be:

{
  network_address = "127.0.0.1:8001"
}

Then transient fields might be:

{
  network_address = "127.0.0.1:8001",
  ip = "127.0.0.1",
  port = 8001
}

something that exists in another field but is returned for convenience and is not actually stored in database.


In future it might open us a door to realize backref dereferencing. Like certificates:each({ with = { "snis" } }). This way the certificates entity could pull also snis. Something that right now is done by: SNIS:list_for_certificate but could be just an addition to DAO functionality if we defined the interface in schema.

kong/db/strategies/postgres/init.lua Outdated Show resolved Hide resolved
@raoxiaoyan
Copy link
Contributor Author

raoxiaoyan commented Jul 18, 2024

I'm wondering whether transient is the best name here 🤔 . What I think we're trying to achieve is adding a field to schema that's actually the reverse of type = "foreign" what sometimes is called backref.

transient sounds to me like a field that could be derived from other fields. For example we'd have somewhere a network address field which values would be:

{
  network_address = "127.0.0.1:8001"
}

Then transient fields might be:

{
  network_address = "127.0.0.1:8001",
  ip = "127.0.0.1",
  port = 8001
}

something that exists in another field but is returned for convenience and is not actually stored in database.

In future it might open us a door to realize backref dereferencing. Like certificates:each({ with = { "snis" } }). This way the certificates entity could pull also snis. Something that right now is done by: SNIS:list_for_certificate but could be just an addition to DAO functionality if we defined the interface in schema.

@nowNick
Thank you for your review. I agree with your part of your points.
My first thought. The transient keyword in Java is used to prevent certain member variables of an object from being serialized. By using it, we can enhance security, reduce serialization overhead, and ensure that only meaningful and necessary data is serialized. Therefore, I have adopted this approach to temporarily store data without persisting it to the database. Additionally, it can support the transformation and storage of other data during the deserialization process (if future support is needed). If we need to perform cascading queries to retrieve the corresponding objects, we might need other attributes (such as one-to-many or many-to-one relationships) to describe the data more appropriately.

@ADD-SP ADD-SP linked an issue Jul 18, 2024 that may be closed by this pull request
1 task
Copy link
Contributor

@nowNick nowNick left a comment

Choose a reason for hiding this comment

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

Ok the Java explanation makes sense 👍 In the future I think we might benefit from backref type in metaschema but let's move one step at a time.

@ADD-SP
Copy link
Contributor

ADD-SP commented Jul 22, 2024

Rebased on master as CI is always red

@outsinre
Copy link
Contributor

outsinre commented Jul 22, 2024

Schema changed. CC @GGabriele

@liverpool8056
Copy link
Contributor

@raoxiaoyan IMHO, the transient is able to exclude fields marked with it from persistence, in other word, these fields should or may be ignored during schema validation. This explains why one of test cases introduced in this PR which hits the endpoint of schema validation /schemas/certificates/validate can pass even though there is no special treatments for the sni field in the certificate json entity in the request body.
However, some previous test cases related to certificate creation fail after removing https://github.com/Kong/kong-ee/blob/2be9144914a6aea395aef2c80a5e1ebf9289ff9b/kong/db/dao/certificates.lua#L70 due to failures in schema validation. This is out of my expectation. WDYT?

@outsinre
Copy link
Contributor

outsinre commented Jul 26, 2024

This method adds schema field and allows snis field when validating certificates. However, the snis field is ignored when validating.

Suppose a scenario:

  1. An Admin API is sent to validate a cert. The body also includes a snis field, like {"error", "not-exist" }.

  2. The code only validates the cert part and returns 200 OK.

  3. Another Admin API is sent to create the cert, and also includes the {"error", "not-exist" }. Will return 200 OK. Therefore, the invalid SNIs would be created, and cause error when doing SSL handshake.

    kong=# select * from snis ;
                      id                  |       created_at       |   name    |            certificate_id            | tags |                ws_id                 |       updated_at
    -------------------------------------- ------------------------ ----------- -------------------------------------- ------ -------------------------------------- ------------------------
     3f8e7c93-aa54-4437-86e8-6845e93f13e8 | 2024-07-26 09:06:00 00 | error     | 5bbb04a4-cd1b-498b-8dc0-64d797ec0f57 |      | d90e3613-56af-439e-acdf-7c5fd468dab8 | 2024-07-26 09:06:00 00
     345baaac-56b9-4480-9ef4-1465cd11c860 | 2024-07-26 09:07:05 00 | not-exist | 5bbb04a4-cd1b-498b-8dc0-64d797ec0f57 |      | d90e3613-56af-439e-acdf-7c5fd468dab8 | 2024-07-26 09:07:05 00
    (2 rows)
    

Thus, we are in a situation where the validation API passes but the SSL handshake fails.

@raoxiaoyan
Copy link
Contributor Author

This method adds schema field and allows snis field when validating certificates. However, the snis field is ignored when validating.

Suppose a scenario:

  1. An Admin API is sent to validate a cert. The body also includes a snis field, like {"error", "not-exist" }.
  2. The code only validates the cert part and returns 200 OK.
  3. Another Admin API is sent to create the cert, and also includes the {"error", "not-exist" }. Will return 200 OK.
kong=# select * from snis ;
                  id                  |       created_at       |   name    |            certificate_id            | tags |                ws_id                 |       updated_at
-------------------------------------- ------------------------ ----------- -------------------------------------- ------ -------------------------------------- ------------------------
 3f8e7c93-aa54-4437-86e8-6845e93f13e8 | 2024-07-26 09:06:00 00 | error     | 5bbb04a4-cd1b-498b-8dc0-64d797ec0f57 |      | d90e3613-56af-439e-acdf-7c5fd468dab8 | 2024-07-26 09:06:00 00
 345baaac-56b9-4480-9ef4-1465cd11c860 | 2024-07-26 09:07:05 00 | not-exist | 5bbb04a4-cd1b-498b-8dc0-64d797ec0f57 |      | d90e3613-56af-439e-acdf-7c5fd468dab8 | 2024-07-26 09:07:05 00
(2 rows)

I didn't catch it. What do you mean?

@raoxiaoyan raoxiaoyan force-pushed the fix/KM-223 branch 2 times, most recently from 671be51 to d1b7864 Compare July 29, 2024 06:08
@pull-request-size pull-request-size bot added size/L and removed size/M labels Jul 29, 2024
@ADD-SP ADD-SP merged commit cb8d046 into master Jul 30, 2024
27 checks passed
@ADD-SP ADD-SP deleted the fix/KM-223 branch July 30, 2024 08:44
@team-gateway-bot
Copy link
Collaborator

Successfully created cherry-pick PR for master:

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

Successfully merging this pull request may close these issues.

None yet

8 participants