Skip to content

API key pair restructure - #9504

Merged
DaanHoogland merged 2 commits into
apache:mainfrom
scclouds:api-keypair-restructure
Mar 9, 2026
Merged

API key pair restructure#9504
DaanHoogland merged 2 commits into
apache:mainfrom
scclouds:api-keypair-restructure

Conversation

@KlausDornsbach

@KlausDornsbachKlausDornsbach commented Aug 8, 2024

Copy link
Copy Markdown
Contributor

Description

API access keypairs are primarily used to support interactions between systems, without the need to create sessions (through user and password authentication). Currently, CloudStack's implementation of API keypairs does not allow you to specify permissions for each keypair, simply using the account's default permissions. Additionally, the number of keypairs is limited to one per user and they have no start and end dates.

An extension of the API keypairs functionality was implemented, adding several new features that increase flexibility and security. It is now possible to specify a subset of permissions (from the base account) for each keypair, as well as create more than one key per user. It is also possible to define start and end dates for the validity of a keypair. A key created without an expiration date will always be valid up until it is deleted. It should be noted that creating API keypairs without specifying permissions just creates an API keypair with all account's base permissions. Also, API keypairs older than this patch will always be viewed as keypairs with full account permissions.

The following endpoints were created:

A new listUserKeys API was added. Through this API the user will be able to specify a single keypairid to fetch its specific properties, or apikeyfilter to return a specific keypair based on an apikey. The user can inform an userid to fetch an user's api keypair list. If no keypairid, apikeyfilter or userid is provided, the API defaults to fetching information on the calling user. The listall property allows for fetching all keypairs in the structure that are visible based on the calling user/keypair permissions, if not specified, it defaults to false, fetching only the apikeys on the level of the calling user/keypair. Also, it is possible to inform showpermissions to list all permissions associated with each returned apikey.

NameDescriptionRequiredDefault
useridid of the owner of the keypairsnonone
keypairidid of the keypairnonone
listalllist all accessable keypairsnofalse
apikeyfilterapikey of they keypairnonone
showpermissionslists all associated apikey permissionsnofalse

The API getUserKeys was modified preserving backwards compatibility. It now fetches the last keypair created for the informed user.

The api registerUserKeys was modified so the new API keypair parameters could be specified on creation:

NameDescriptionRequiredExampleDefault
iduser idYesb8914774-771e-11ee-8e59-5254003754dcnone
namename of the keypairNoMyKeyuserId + " - API Keypair"
startdatedate when key becomes validNo2024-04-09none
enddatedate when key expiresNo2024-04-09never expires
descriptionkeypair descriptionNoread only permissionsnone
ruleslist of API access rulesNorules[1].rule=list* rules[1].permission=allowall user API permissions based on Account Role

A new keypair deletion API was added (deleteUserKeys). It will accept only one required argument, the keypair id.

NameDescriptionRequired
keypairidid of the keypairyes

I also added a listUserKeyRules api, allowing the user to list the rules associated with an API keypair.

NameDescriptionRequired
keypairidid of the keypairyes

Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)
  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (improves an existing feature and functionality)
  • Cleanup (Code refactoring and cleanup, that may add test cases)
  • build/CI
  • test (unit or integration test code)

Feature/Enhancement Scale or Bug Severity

Feature/Enhancement Scale

  • Major
  • Minor

Bug Severity

  • BLOCKER
  • Critical
  • Major
  • Minor
  • Trivial

How Has This Been Tested?

API Key Creation and Basic Testing

Single Key (via UI):

  1. I was able to create API keypairs through the UI through the button on the top right of the user view;
  2. Through Cloud Monkey, validated that the keypair had the same permissions as the base user by calling a series of APIs;

Multiple Keys (via Cloud Monkey):

  1. Created multiple keys;
  2. Validated the operation was successful on the DB;
  3. Tested creating a key that was not valid and would become valid in the future, with success;
  4. Tested creating a key that was valid and would become invalid in the future, with success;
  5. Tested trying to create keys that were already invalid and got errors;
  6. All permissions of the API key pairs were consistent with each key pair tested.

Permissions Validation

Tested the permissions of keyrules listing, keypair listing, keypair deletion and keypair cretion with the following user/account/domain setup:

  • domain /ROOT
    • account root admin

      • user root admin
      • user user1
    • domain subdomain

      • account domain admin
        • user domain admin
      • account userAccount
        • user user2
        • user user3

The following table describes the results obtained when the user on the first column attempted to operate on the keypairs of users on the first row (V: operation was possible, F: operation was not possible).

userrootAdmuser1domainAdmuser2user3
rootAdmVVVVV
user1VVVVV
domainAdmFFVVV
user2FFFVF
user3FFFFV

Migration to api_keypair Table

  1. A key was created for a read-only user
  2. The database was updated from version 4.19 to 4.20
  3. The API key data was successfully migrated to the api_keypair table, with the corresponding columns in the user table deleted.
  4. Confirmed correct permission handling of the api key.

General validations

  • Could not create an API keypair with more permissions than the base keypair.
  • Deleting system keys was not possible.
  • After deleting a user or account, the API keypairs were invalidated.

@codecov

codecovBot commented Aug 12, 2024

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 16.50738% with 961 lines in your changes missing coverage. Please review.
✅ Project coverage is 17.92%. Comparing base (7ad68aa) to head (b6b1b5f).
⚠️ Report is 2 commits behind head on main.

Files with missing linesPatch %Lines
...c/main/java/com/cloud/user/AccountManagerImpl.java31.80%182 Missing and 11 partials ⚠️
...he/cloudstack/api/response/ApiKeyPairResponse.java0.00%127 Missing ⚠️
...ck/api/command/admin/user/RegisterUserKeysCmd.java0.00%94 Missing ⚠️
...n/java/org/apache/cloudstack/acl/ApiKeyPairVO.java25.60%93 Missing ⚠️
...src/main/java/com/cloud/api/ApiResponseHelper.java0.00%61 Missing ⚠️
...g/apache/cloudstack/acl/dao/ApiKeyPairDaoImpl.java0.00%43 Missing ⚠️
...dstack/api/command/admin/user/ListUserKeysCmd.java0.00%35 Missing ⚠️
...g/apache/cloudstack/acl/ApiKeyPairManagerImpl.java0.00%33 Missing ⚠️
...tack/api/command/admin/user/DeleteUserKeysCmd.java0.00%30 Missing ⚠️
.../cloudstack/discovery/ApiDiscoveryServiceImpl.java14.28%28 Missing and 2 partials ⚠️
... and 31 more
Additional details and impacted files
@@ Coverage Diff @@## main #9504 +/- ##
==========================================
Coverage 17.92% 17.92% - Complexity 16156 16176 +20 
==========================================
Files 5939 5949 +10 Lines 533192 534058 +866 Branches 65239 65301 +62 ==========================================
+ Hits 95591 95748 +157 - Misses 426859 427553 +694 - Partials 10742 10757 +15 
FlagCoverage Δ
uitests3.66% <ø> (ø)
unittests19.03% <16.50%> (-0.01%)⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@DaanHoogland

Copy link
Copy Markdown
Contributor

nice feature @KlausDornsbach , some suggestions,

  1. would it make sense to be able to delete a kay based on name?
  2. also is admin allowed to delete keys for other users? (would make sense from a maintainance point of view, would it?)

@KlausDornsbach

Copy link
Copy Markdown
ContributorAuthor

Hey @DaanHoogland, thanks for taking a look!

It would make sense to be able to delete a keypair by name, we would just need to block users from creating multiple API keypairs with the same name.

At the moment an admin is allowed to delete keypairs from users it has access, for example, a root admin user could delete any keypair in the platform, domain admin users can delete any keypair in the domain, normal users can only delete their own keys. These permissions are also true for visualization and creation APIs.

@DaanHoogland

Copy link
Copy Markdown
Contributor

It would make sense to be able to delete a keypair by name, we would just need to block users from creating multiple API keypairs with the same name.

Well, I think a unique constraint on UserId/KeyPairName makes sense also from a usability sense.

At the moment an admin is allowed to delete keypairs from users it has access, for example, a root admin user could delete any keypair in the platform, domain admin users can delete any keypair in the domain, normal users can only delete their own keys. These permissions are also true for visualization and creation APIs.

👍

@rajujithrajujith self-assigned this Aug 19, 2024
@rajujith

Copy link
Copy Markdown
Contributor

@blueorangutan package

@github-actions

Copy link
Copy Markdown

This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch.

@apacheapache deleted a comment from blueorangutanAug 20, 2024
@apacheapache deleted a comment from blueorangutanAug 20, 2024
@apacheapache deleted a comment from blueorangutanAug 20, 2024
@apacheapache deleted a comment from blueorangutanAug 20, 2024
@apacheapache deleted a comment from blueorangutanAug 20, 2024
@apacheapache deleted a comment from blueorangutanAug 20, 2024
@DaanHoogland

Copy link
Copy Markdown
Contributor

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

@DaanHoogland a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✖️ el8 ✖️ el9 ✖️ debian ✖️ suse15. SL-JID 10714

@rajujith

Copy link
Copy Markdown
Contributor

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

@rajujith a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✖️ el8 ✖️ el9 ✖️ debian ✖️ suse15. SL-JID 10720

@rajujith

Copy link
Copy Markdown
Contributor

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

@rajujith a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ debian ✔️ suse15. SL-JID 10736

@DaanHoogland

Copy link
Copy Markdown
Contributor

@blueorangutan test

@GutoVeronezi

Copy link
Copy Markdown
Contributor

good functionality and looks good so far, however, this should go into a non-LTS first and only after extensive testing. it is a cross cutting concern and hence brings risks adherent to such code

I totally agree with you; LTS are supposed to be as stable as possible. We should also apply the same criteria to every other PR with extensive or critical changes as well 😃

@DaanHoogland

Copy link
Copy Markdown
Contributor

good functionality and looks good so far, however, this should go into a non-LTS first and only after extensive testing. it is a cross cutting concern and hence brings risks adherent to such code

I totally agree with you; LTS are supposed to be as stable as possible. We should also apply the same criteria to every other PR with extensive or critical changes as well 😃

I was kind of inviting this to 23, but yes, if it is a cross-cutting concern it should go in the non-LTS release first. Extensive or critical are gliding scales (and maybe cross-cutting as well, but certainly less so)

@GutoVeronezi

Copy link
Copy Markdown
Contributor

I was kind of inviting this to 23, but yes, if it is a cross-cutting concern it should go in the non-LTS release first. Extensive or critical are gliding scales (and maybe cross-cutting as well, but certainly less so)

I was under impression that 4.23 would be a regular release (the wiki states so);

image

Thus, it would make sense to address this PR on release 4.23. 5 months seems enough time to review, test, and mature the PR. I also plan to test it in a few weeks.

@DaanHoogland

Copy link
Copy Markdown
Contributor

As our ex-colleague always says @GutoVeronezi , “we are in violent agreement”!

Comment threadserver/src/main/java/com/cloud/api/ApiServer.java Outdated
@github-actions

Copy link
Copy Markdown

This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch.

@bernardodemarco

Copy link
Copy Markdown
Member

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

@bernardodemarco a [SL] Jenkins job has been kicked to build packages. It will be bundled with no SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 16988

@sureshanaparti

Copy link
Copy Markdown
Contributor

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

@sureshanaparti a [SL] Jenkins job has been kicked to build packages. It will be bundled with no SystemVM templates. I'll keep you posted as I make progress.

@github-actions

Copy link
Copy Markdown

This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch.

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 17001

@bernardodemarco

Copy link
Copy Markdown
Member

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

@bernardodemarco a [SL] Jenkins job has been kicked to build packages. It will be bundled with no SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 17004

@bernardodemarco

Copy link
Copy Markdown
Member

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

@bernardodemarco a [SL] Jenkins job has been kicked to build packages. It will be bundled with no SystemVM templates. I'll keep you posted as I make progress.

@bernardodemarco

Copy link
Copy Markdown
Member

@shwstppr@sureshanaparti@DaanHoogland@weizhouapache@GutoVeronezi@winterhazel@JoaoJandre@hsato03@erikbocks, guys, this one is finally ready for review and testing. Below are the test descriptions that I have performed:

TestDescriptionExpected result?
1Key pair without explicit rulesVerified that when creating a key pair without explicit rules, all the account's role permissions are inferred as the permissions of the key pair.Yes
2Key pair with explicit rulesVerified that when creating a key pair with explicit rules, it is only granted access to the key pair's rules.Yes
3Change account's role rules after API keys have been created.Verified that the key pair never has access to more APIs that its role has.Yes
4Key pairs creation with more permissions that the caller's roleVerified that it is not possible to create key pairs with more permission than the caller's set of permissions.Yes
5Key pair with start and end dates.Verified that the startdate and enddate attributes of the key pair are correctly respected.Yes
6Key pairs creation from the UI.Accessed the details page of an user and successfully generated an API key pair for it.Yes
7Invalidation of API key pairs after user/account deletionVerified that after deleting accounts and users, their API key pairs are correctly deleted.Yes
8Invalidation of API key pairs when they are disabledVerified that it is not possible to use the API key pairs when they are disabled for their accounts and users.Yes
9High-level workflows of the APIs getUserKeys, registerUserKeys, deleteUserKeys, listUserKeyRules, listUserKeysVerified the execution of such APIs, including access validation checks.Yes
10Deletion of system keysTried to delete the keys of the baremetal-system-account account and verified that an error message was returned. Verified the possibility of removing the key pair when the baremetal.provision.done.notification is disabled.Yes
11Migration to the new DB's schemaVerified that the migration of active API key pairs from the cloud.user table to the cloud.api_keypair one was performed successfully.Yes

@bernardodemarco

Copy link
Copy Markdown
Member

@shwstppr@sureshanaparti@DaanHoogland@weizhouapache can we run the integration tests for the PR, please?

btw, the simulator tests are failing across multiple PRs (see #12683 and #12680, for instance). Thus, they do not seem to be related with the current PR.

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 17010

@DaanHoogland

Copy link
Copy Markdown
Contributor

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

@DaanHoogland a [SL] Jenkins job has been kicked to build packages. It will be bundled with no SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 17014

@DaanHoogland

Copy link
Copy Markdown
Contributor

@blueorangutan test

@blueorangutan

Copy link
Copy Markdown

@DaanHoogland a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests

@blueorangutan

Copy link
Copy Markdown

[SF] Trillian test result (tid-15573)
Environment: kvm-ol8 (x2), zone: Advanced Networking with Mgmt server ol8
Total time taken: 53151 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr9504-t15573-kvm-ol8.zip
Smoke tests completed. 145 look OK, 5 have errors, 0 did not run
Only failed and skipped tests results shown below:

TestResultTime (s)Test File
test_03_ping_in_ssvm_successFailure14.66test_diagnostics.py
test_04_extract_IsoFailure1.10test_iso.py
ContextSuite context=TestListIdsParams>:teardownError1.17test_list_ids_parameter.py
test_01_snapshot_root_diskError5.16test_snapshots.py
test_02_list_snapshots_with_removed_data_storeError47.14test_snapshots.py
test_02_list_snapshots_with_removed_data_storeError47.15test_snapshots.py
ContextSuite context=TestSnapshotStandaloneBackup>:teardownError32.48test_snapshots.py
test_01_snapshot_usageError22.94test_usage.py
test_01_vpn_usageError1.12test_usage.py

@bernardodemarcobernardodemarco mentioned this pull request May 22, 2026
9 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

12 participants

@KlausDornsbach@DaanHoogland@rajujith@blueorangutan@nicoschmdt@shwstppr@bernardodemarco@GutoVeronezi@sureshanaparti@winterhazel@weizhouapache@harikrishna-patnala