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

feat: support read-write device.id in tedge cert/connect #3326

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

rina23q
Copy link
Member

@rina23q rina23q commented Jan 10, 2025

Proposed changes

This PR aims to open up device.id as read-write key. This is the last piece of supporting basic authentication, as it needs device.id but not need for device cert.

TODOs:

tedge cert/connect part

  • tedge cert create writes device.id in tedge.toml explicitly.
  • tedge connect returns an error if device.id mismatches the certificate's CN. The only exception is when c8y.auth_mode is basic.
  • Updated smart_rest_one system test to confirm that tedge connect c8y uses device.id directly when using basic auth.
  • tedge cert create-csr also sets device.id if not configured.
  • tedge cert create should work without --device-id option when device.id is already set.
  • Don't overwrite a certificate and device.id when the values of option --device-id and config device.id are conflicting. This case should return an error.

tedge_config part (originally started in the PR #3318 by @jarhodes314 )

doc part

  • Create SmartREST1.0 support doc
  • Update tedge cert doc
  • Update tedge conect doc

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Improvement (general improvements like code refactoring that doesn't explicitly fix a bug or add any new functionality)
  • Documentation Update (if none of the other choices apply)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Paste Link to the issue

#3242

Checklist

  • I have read the CONTRIBUTING doc
  • I have signed the CLA (in all commits with git commit -s)
  • I ran cargo fmt as mentioned in CODING_GUIDELINES
  • I used cargo clippy as mentioned in CODING_GUIDELINES
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if appropriate)

Further comments

Copy link
Contributor

@didier-wenzek didier-wenzek left a comment

Choose a reason for hiding this comment

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

The command to create a CSR must also be updated to set the device id.

Copy link
Contributor

@didier-wenzek didier-wenzek left a comment

Choose a reason for hiding this comment

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

If the device id has been set using tedge config set device.id, then the device id should no more be mandatory for tedge cert create.

We also need to take care of the paths for the cloud specific certificates.
For instance, the following sequence of command is error prone:

# Trying to create a certificate for an unknown cloud profile (okay: the error is detected)
$ tedge cert create --device-id demo-c8y c8y --profile foo
Error: missing configuration parameter

Caused by:
Unknown profile `foo` for the multi-profile property c8y

# Creating the cloud profile
$ tedge config set c8y.device.id device-c8y-foo  --profile foo

# Now that the cloud profile exists, the cert creat command runs
# BUT
#    - --device-id is required while set in the config
#    - the value set on the command line erases the config
#    - the certificate is created globally (because no specific paths were configured for this profile)
$ tedge cert create --device-id some-other-device-id c8y --profile foo
Error: failed to create a test certificate for the device some-other-device-id.

Caused by:
A certificate already exists and would be overwritten.
Existing file: "/etc/tedge/device-certs/demo-device-888.pem"
Run `tedge cert remove` first to generate a new certificate.

@rina23q
Copy link
Member Author

rina23q commented Jan 13, 2025

@didier-wenzek
Actually this error occurs even now if user doesn't set any keys for a profile beforehand.

# Trying to create a certificate for an unknown cloud profile (okay: the error is detected)
$ tedge cert create --device-id demo-c8y c8y --profile foo
Error: missing configuration parameter

Caused by:
Unknown profile `foo` for the multi-profile property c8y

For the rest, I would like to implement to have the consistent behavour as create-csr, which uses the value of device.id if --device-id is not given.

However, on the condition, if device.id is already configured, but --device-id option is given with the different name as you tried, what is the expected behaviour? Returns an error as they are conflictiing?

@didier-wenzek
Copy link
Contributor

@didier-wenzek Actually this error occurs even now if user doesn't set any keys for a profile beforehand.

In that case this is a bug. tedge cert create should not create a global certificate when the request if for a specific cloud.

For the rest, I would like to implement to have the consistent behavour as create-csr, which uses the value of device.id if --device-id is not given.

Perfect. One just to be cautious taking the most specific device id (i.e. the id for the requested cloud and profile if given).

However, on the condition, if device.id is already configured, but --device-id option is given with the different name as you tried, what is the expected behaviour? Returns an error as they are conflictiing?

Yes raising an error is the way to go. But make sure the comparison is done on the device id specific for the requested cloud. I.e. if device.id is set but the command provides a different one for c8y, then this is okay.

Copy link
Contributor

github-actions bot commented Jan 16, 2025

Robot Results

✅ Passed ❌ Failed ⏭️ Skipped Total Pass % ⏱️ Duration
557 0 2 557 100 1h32m35.761493999s

@rina23q rina23q force-pushed the feature/3242/writable-device-id-3 branch from 7dcb459 to 77e1ecd Compare January 16, 2025 15:53
@rina23q rina23q temporarily deployed to Test Pull Request January 16, 2025 15:53 — with GitHub Actions Inactive
@reubenmiller reubenmiller added theme:configuration Theme: Configuration management theme:c8y Theme: Cumulocity related topics theme:certificates theme:mqtt Theme: mqtt and mosquitto related topics and removed theme:c8y Theme: Cumulocity related topics theme:mqtt Theme: mqtt and mosquitto related topics labels Jan 16, 2025
@reubenmiller reubenmiller removed theme:c8y Theme: Cumulocity related topics theme:certificates labels Jan 16, 2025
Copy link
Contributor

@jarhodes314 jarhodes314 left a comment

Choose a reason for hiding this comment

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

From a quick test this seems to be working well. It will be much easier to use the CLI with the persisted device id.

Comment on lines +307 to +314
#[test_case("c8y-foo-test", Some("c8y-foo-test"), Some(CloudArg::C8y{ profile: Some("foo".parse().unwrap()) }), toml::toml!{
[device]
id = "test"
[c8y.device]
id = "c8y-test"
})]
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this case actually occur in practice? If someone hasn't got any configurations for a profile, the profile doesn't exist and that will cause an error elsewhere in tedge cert create.

Copy link
Member Author

Choose a reason for hiding this comment

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

In practice, tedge cert create will return an error because no profile for "foo" exists. So the following toml fie is more realistic. Though the result get_device_id() is the same.

[device]
id = "test"
[c8y.device]
id = "c8y-test"
[c8y.profiles.foo.device]
cert_path = "/path/to/cert.pem"
key_path = "/path/to/key.pem"

r#"The given device ID '{input_id}' doesn't match the one in the config '{config_id}'.
Run `tedge config unset {writable_key}` first to unset the device ID."#
)]
UnmatchedDeviceId {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
UnmatchedDeviceId {
MismatchedDeviceId {

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed in ed40433

@@ -102,6 +102,10 @@ impl TEdgeConfigLocation {
Ok(TEdgeConfig::from_dto(&dto, self))
}

pub fn load_dto_with_file_and_env(&self) -> Result<TEdgeConfigDto, TEdgeConfigError> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
pub fn load_dto_with_file_and_env(&self) -> Result<TEdgeConfigDto, TEdgeConfigError> {
pub fn load_dto_from_toml_and_env(&self) -> Result<TEdgeConfigDto, TEdgeConfigError> {

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed in bfc6e14

jarhodes314 and others added 9 commits January 17, 2025 13:46
Examples:
`tedge cert create --device-id foo`
-> `device.id` is set to foo

`tedge cert create --device-id bar c8y`
-> `c8y.device.id` is set to bar

`tedge cert create --device-id baz c8y --profile new`
-> `c8y.profiles.new.device.id` is set to baz

Signed-off-by: Rina Fujino <[email protected]>
* tedge connect c8y uses device.id directly.
The CN from certificate is no longer used to determine device.id
* tedge connect c8y returns an error if device.id mismatches
the certificate's CN when auth method is certificate

Signed-off-by: Rina Fujino <[email protected]>
@rina23q rina23q force-pushed the feature/3242/writable-device-id-3 branch from 77e1ecd to 247d7f8 Compare January 17, 2025 14:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
theme:configuration Theme: Configuration management
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants