Skip to content

Fix NPE with ApiKeyPair during listApis call (from cmk) - #13149

Open
sureshanaparti wants to merge 3 commits into
apache:mainfrom
shapeblue:api-keypair-npe-fix
Open

Fix NPE with ApiKeyPair during listApis call (from cmk)#13149
sureshanaparti wants to merge 3 commits into
apache:mainfrom
shapeblue:api-keypair-npe-fix

Conversation

@sureshanaparti

@sureshanapartisureshanaparti commented May 12, 2026

Copy link
Copy Markdown
Contributor

Description

This PR fixes NPE issue with ApiKeyPair during listApis call (from cmk).

(localcloud) 🐱 > sync
[debug] ExecLine line:sync
[debug] ExecCmd args: sync
[debug] NewAPIRequest API request URL:http://10.0.33.254:8080/client/api?apiKey=LIN6rqXuaJwMPfGYFh13qDwYz5VNNz1J2J6qIOWcd3oLQOq0WtD4CwRundBL6rzXToa3lQOC_vKjI3nkHtiD8Q&command=listApis&expires=2026-05-12T10%3A52%3A21Z&listall=true&response=json&signatureversion=3
[debug] Using HTTP POST for the request: http://10.0.33.254:8080/client/api
⣷ 😸 discovering APIs, please wait...[debug] NewAPIRequest response status code:401
[debug] Login POST URL:http://10.0.33.254:8080/client/apimap[command:[login] domain:[/] password:[password] response:[json] username:[admin]]
[debug] Login POST response status code:200
[debug] Login response body:{"loginresponse":{"username":"admin","userid":"0058d371-493c-11f1-8b72-1e00f0000291","domainid":"a728ab4b-493b-11f1-8b72-1e00f0000291","timeout":1800,"account":"admin","firstname":"admin","lastname":"cloud","type":"1","timezone":"UTC","timezoneoffset":"0.0","registered":"false","sessionkey":"WjoANDlHyxTdO9Aa_LXOa4rei34","is2faenabled":"false","is2faverified":"true","issuerfor2fa":"CloudStack","managementserverid":"c5a6dd86-fead-4397-8cf5-55250df33c24"}}
[debug] Login sessionkey:WjoANDlHyxTdO9Aa_LXOa4rei34
[debug] Checking if 2FA is enabled and verified for the user map[account:admin domainid:a728ab4b-493b-11f1-8b72-1e00f0000291 firstname:admin is2faenabled:false is2faverified:true issuerfor2fa:CloudStack lastname:cloud managementserverid:c5a6dd86-fead-4397-8cf5-55250df33c24 registered:false sessionkey:WjoANDlHyxTdO9Aa_LXOa4rei34 timeout:1800 timezone:UTC timezoneoffset:0.0 type:1 userid:0058d371-493c-11f1-8b72-1e00f0000291 username:admin]
[debug] 2FA is not enabled for the user, skipping 2FA validation
[debug] NewAPIRequest API request URL:http://10.0.33.254:8080/client/api?apiKey=LIN6rqXuaJwMPfGYFh13qDwYz5VNNz1J2J6qIOWcd3oLQOq0WtD4CwRundBL6rzXToa3lQOC_vKjI3nkHtiD8Q&command=listApis&expires=2026-05-12T10%3A52%3A21Z&listall=true&response=json&sessionkey=WjoANDlHyxTdO9Aa_LXOa4rei34&signature=9kJbbP3gtVaU2N6XZzKPmYRDYFE%3D&signatureversion=3
[debug] Using HTTP POST for the request: http://10.0.33.254:8080/client/api
[debug] NewAPIRequest response body:{"listapisresponse":{"uuidList":[],"errorcode":530,"cserrorcode":9999,"errortext":"Cannot invoke \"org.apache.cloudstack.acl.apikeypair.ApiKeyPair.getAccountId()\" because \"apiKeyPair\" is null"}}
🙈 Error: (HTTP 530, error code 9999) Cannot invoke "org.apache.cloudstack.acl.apikeypair.ApiKeyPair.getAccountId()" because "apiKeyPair" is null
(localcloud) 🐱 > 
2026-05-12 10:37:22,051 DEBUG [c.c.a.ApiServlet] (qtp253011924-24:[ctx-313ce9a0]) (logid:d4f7907a) ===START=== 10.0.33.254 -- POST apiKey=LIN6rqXuaJwMPfGYFh13qDwYz5VNNz1J2J6qIOWcd3oLQOq0WtD4CwRundBL6rzXToa3lQOC_vKjI3nkHtiD8Q command=listApis expires=2026-05-12T10:52:21Z listall=true response=json sessionkey=WjoANDlHyxTdO9Aa_LXOa4rei34 signature=9kJbbP3gtVaU2N6XZzKPmYRDYFE= signatureversion=3 2026-05-12 10:37:22,054 DEBUG [c.c.a.ApiServer] (qtp253011924-24:[ctx-313ce9a0, ctx-e535ff0f]) (logid:d4f7907a) CIDRs from which account 'Account [{"accountName":"admin","id":2,"uuid":"00583461-493c-11f1-8b72-1e00f0000291"}]' is allowed to perform API calls: 0.0.0.0/0,::/0
2026-05-12 10:37:22,055 INFO [o.a.c.a.DynamicRoleBasedAPIAccessChecker] (qtp253011924-24:[ctx-313ce9a0, ctx-e535ff0f]) (logid:d4f7907a) Account [Account [{"accountName":"admin","id":2,"uuid":"00583461-493c-11f1-8b72-1e00f0000291"}]] is Root Admin and there aren't any API key pair permissions involved, thus, all APIs are allowed.
2026-05-12 10:37:22,055 DEBUG [o.a.c.a.StaticRoleBasedAPIAccessChecker] (qtp253011924-24:[ctx-313ce9a0, ctx-e535ff0f]) (logid:d4f7907a) RoleService is enabled. We will use it instead of StaticRoleBasedAPIAccessChecker.
2026-05-12 10:37:22,055 DEBUG [o.a.c.r.ApiRateLimitServiceImpl] (qtp253011924-24:[ctx-313ce9a0, ctx-e535ff0f]) (logid:d4f7907a) API rate limiting is disabled. We will not use ApiRateLimitService.
2026-05-12 10:37:22,056 WARN [c.c.a.d.ParamGenericValidationWorker] (qtp253011924-24:[ctx-313ce9a0, ctx-e535ff0f]) (logid:d4f7907a) Received unknown parameters for command listApis. Unknown parameters : listall
2026-05-12 10:37:22,059 ERROR [c.c.a.ApiServer] (qtp253011924-24:[ctx-313ce9a0, ctx-e535ff0f]) (logid:d4f7907a) unhandled exception executing api command: [Ljava.lang.String;@1e71e72d java.lang.NullPointerException: Cannot invoke "org.apache.cloudstack.acl.apikeypair.ApiKeyPair.getAccountId()" because "apiKeyPair" is null
at com.cloud.user.AccountManagerImpl.getAllKeypairPermissions(AccountManagerImpl.java:3585)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:569)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
at jdk.proxy3/jdk.proxy3.$Proxy104.getAllKeypairPermissions(Unknown Source)
at org.apache.cloudstack.discovery.ApiDiscoveryServiceImpl.listApisForKeyPair(ApiDiscoveryServiceImpl.java:357)
at org.apache.cloudstack.discovery.ApiDiscoveryServiceImpl.listApis(ApiDiscoveryServiceImpl.java:283)
at org.apache.cloudstack.api.command.user.discovery.ListApisCmd.execute(ListApisCmd.java:55)
at com.cloud.api.ApiDispatcher.dispatch(ApiDispatcher.java:173)
at com.cloud.api.ApiServer.queueCommand(ApiServer.java:883)
at com.cloud.api.ApiServer.handleRequest(ApiServer.java:697)
at com.cloud.api.ApiServlet.processRequestInContext(ApiServlet.java:414)
at com.cloud.api.ApiServlet$1.run(ApiServlet.java:191)

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

Screenshots (if appropriate):

How Has This Been Tested?

How did you try to break this feature and the system with this change?

@sureshanaparti

Copy link
Copy Markdown
ContributorAuthor

@KlausDornsbach can you review this.

@weizhouapacheweizhouapache added this to the 4.23.0 milestone May 12, 2026
@sureshanaparti

Copy link
Copy Markdown
ContributorAuthor

@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.

@codecov

codecovBot commented May 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 3.46%. Comparing base (3c1f031) to head (5d8d7ef).
⚠️ Report is 173 commits behind head on main.

❗ There is a different number of reports uploaded between BASE (3c1f031) and HEAD (5d8d7ef). Click for more details.

HEAD has 1 upload less than BASE
FlagBASE (3c1f031)HEAD (5d8d7ef)
unittests10
Additional details and impacted files
@@ Coverage Diff @@## main #13149 +/- ##
=============================================
- Coverage 18.08% 3.46% -14.63% 
=============================================
Files 6037 479 -5558 Lines 542611 41162 -501449 Branches 66433 7793 -58640 =============================================
- Hits 98136 1426 -96710 + Misses 433448 39543 -393905 + Partials 11027 193 -10834 
FlagCoverage Δ
uitests3.46% <ø> (-0.06%)⬇️
unittests?

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

☔ View full report in Codecov by Harness.
📢 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.

@blueorangutan

Copy link
Copy Markdown

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

@winterhazel

winterhazel commented May 12, 2026

Copy link
Copy Markdown
Member

@KlausDornsbach can you review this.

@sureshanaparti, @KlausDornsbach is not active in the community anymore. I am asking @bernardodemarco to review this, as he was responsible for maintaning the keypairs PR.

@bernardodemarco

Copy link
Copy Markdown
Member

@sureshanaparti, thanks for the PR! I'll try to review and test it during this week.

@bernardodemarcobernardodemarco left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

tested locally, LGTM

@sureshanaparti

Copy link
Copy Markdown
ContributorAuthor

@blueorangutan test

@sureshanaparti

Copy link
Copy Markdown
ContributorAuthor

@blueorangutan test

@blueorangutan

Copy link
Copy Markdown

@sureshanaparti 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-16105)
Environment: kvm-ol8 (x2), zone: Advanced Networking with Mgmt server ol8
Total time taken: 83766 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr13149-t16105-kvm-ol8.zip
Smoke tests completed. 146 look OK, 5 have errors, 0 did not run
Only failed and skipped tests results shown below:

TestResultTime (s)Test File
test_vm_backup_create_vm_from_backupFailure607.91test_backup_recovery_nas.py
test_vm_backup_lifecycleError0.09test_backup_recovery_nas.py
ContextSuite context=TestSharedFSLifecycle>:setupError0.00test_sharedfs_lifecycle.py
test_10_attachAndDetach_isoFailure607.09test_vm_life_cycle.py
test_01_create_vm_snapshotsFailure606.86test_vm_snapshots.py
test_02_revert_vm_snapshotsFailure600.77test_vm_snapshots.py
test_03_delete_vm_snapshotsFailure0.02test_vm_snapshots.py
test_01_create_volumeFailure612.29test_volumes.py
test_01_root_volume_encryptionFailure709.39test_volumes.py
test_02_data_volume_encryptionFailure651.09test_volumes.py
test_03_root_and_data_volume_encryptionFailure664.59test_volumes.py
test_02_attach_volumeFailure1275.67test_volumes.py
test_02_attach_volumeFailure1275.68test_volumes.py
test_03_download_attached_volumeFailure666.82test_volumes.py
test_04_delete_attached_volumeFailure665.63test_volumes.py
test_05_detach_volumeFailure753.74test_volumes.py
test_06_download_detached_volumeFailure851.12test_volumes.py
test_07_resize_failFailure661.72test_volumes.py
test_08_resize_volumeFailure670.15test_volumes.py
test_09_delete_detached_volumeFailure670.09test_volumes.py
test_10_list_volumesFailure660.42test_volumes.py
test_11_attach_volume_with_unstarted_vmFailure761.83test_volumes.py
test_12_resize_volume_with_only_size_parameterFailure667.04test_volumes.py
test_13_migrate_volume_and_change_offeringFailure802.31test_volumes.py
test_14_delete_volume_delete_protectionFailure664.04test_volumes.py

@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.

@kiranchavalakiranchavala left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@sureshanaparti

Getting the following error on ol8

(localcloud) 🐱 > sync
panic: interface conversion: interface {} is nil, not []interface {}
goroutine 1 [running]:
github.com/apache/cloudstack-cloudmonkey/config.(*Config).UpdateCache(0xc0000e0120?, 0xc0013b0390)
/home/shwstppr/lab/shapeblue/cloudstack-cloudmonkey/config/cache.go:115 +0x1338
github.com/apache/cloudstack-cloudmonkey/cmd.init.4.func1(0xc0011ab740)
/home/shwstppr/lab/shapeblue/cloudstack-cloudmonkey/cmd/sync.go:35 +0xd0
github.com/apache/cloudstack-cloudmonkey/cli.ExecCmd({0xc001330d30, 0x1, 0x1}, 0x0)
/home/shwstppr/lab/shapeblue/cloudstack-cloudmonkey/cli/exec.go:64 +0x1bb
github.com/apache/cloudstack-cloudmonkey/cli.ExecLine({0xc00133d420, 0x4})
/home/shwstppr/lab/shapeblue/cloudstack-cloudmonkey/cli/exec.go:51 +0x21b
github.com/apache/cloudstack-cloudmonkey/cli.ExecPrompt()
/home/shwstppr/lab/shapeblue/cloudstack-cloudmonkey/cli/prompt.go:84 +0x26e
main.main()
/home/shwstppr/lab/shapeblue/cloudstack-cloudmonkey/cmk.go:101 +0x7f1

@sureshanaparti

sureshanaparti commented May 20, 2026

Copy link
Copy Markdown
ContributorAuthor

@sureshanaparti

Getting the following error on ol8

(localcloud) 🐱 > sync
panic: interface conversion: interface {} is nil, not []interface {}
goroutine 1 [running]:
github.com/apache/cloudstack-cloudmonkey/config.(*Config).UpdateCache(0xc0000e0120?, 0xc0013b0390)
/home/shwstppr/lab/shapeblue/cloudstack-cloudmonkey/config/cache.go:115 +0x1338
github.com/apache/cloudstack-cloudmonkey/cmd.init.4.func1(0xc0011ab740)
/home/shwstppr/lab/shapeblue/cloudstack-cloudmonkey/cmd/sync.go:35 +0xd0
github.com/apache/cloudstack-cloudmonkey/cli.ExecCmd({0xc001330d30, 0x1, 0x1}, 0x0)
/home/shwstppr/lab/shapeblue/cloudstack-cloudmonkey/cli/exec.go:64 +0x1bb
github.com/apache/cloudstack-cloudmonkey/cli.ExecLine({0xc00133d420, 0x4})
/home/shwstppr/lab/shapeblue/cloudstack-cloudmonkey/cli/exec.go:51 +0x21b
github.com/apache/cloudstack-cloudmonkey/cli.ExecPrompt()
/home/shwstppr/lab/shapeblue/cloudstack-cloudmonkey/cli/prompt.go:84 +0x26e
main.main()
/home/shwstppr/lab/shapeblue/cloudstack-cloudmonkey/cmk.go:101 +0x7f1

@kiranchavala no user with that api key, re-check with valid key.

2026-05-20 08:35:12,286 DEBUG [c.c.a.ApiServer] (qtp253011924-21:[ctx-c42ab8fc, ctx-95d85cb5]) (logid:3f28955f) apiKey does not map to a valid user -- ignoring request, apiKey: LIN6rqXuaJwMPfGYFh13qDwYz5VNNz1J2J6qIOWcd3oLQOq0WtD4CwRundBL6rzXToa3lQOC_vKjI3nkHtiD8Q
mysql> SELECT user_id, api_key, created FROM cloud.api_keypair;
+---------+----------------------------------------------------------------------------------------+---------------------+
| user_id | api_key | created |
+---------+----------------------------------------------------------------------------------------+---------------------+
| 3 | DgNbW4qqDYY9dTTxOW0AV6qI2dDvXtwlbJZtfGSDjfP5zhwuDx6FwXAjT6ARMAmvYxfEIlbCAGpfU1Rx5en6kg | 2026-05-19 11:23:47 |
+---------+----------------------------------------------------------------------------------------+---------------------+
1 row in set (0.00 sec)

cmk also need a fix to address this error: (created issue: apache/cloudstack-cloudmonkey#211)

[debug] Using HTTP POST for the request: http://10.0.33.110:8080/client/api
[debug] NewAPIRequest response body:{"listapisresponse":{}}
panic: interface conversion: interface {} is nil, not []interface {}

@sureshanaparti

Copy link
Copy Markdown
ContributorAuthor

@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.

@blueorangutan

Copy link
Copy Markdown

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

@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

@DaanHooglandDaanHoogland left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

clgtm

@winterhazel

winterhazel commented Jun 19, 2026

Copy link
Copy Markdown
Member

@sureshanaparti could you have a look at #13149 (comment)?

@sureshanaparti ping. It would be nice to include this fix in 4.23

CopilotAI review requested due to automatic review settings July 8, 2026 07:37
@sureshanaparti

Copy link
Copy Markdown
ContributorAuthor

@blueorangutan package

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses a NullPointerException when listApis is called with an API key that does not resolve to an ApiKeyPair, by adding null-handling in API key pair lookup paths within AccountManagerImpl.

Changes:

  • Add null checks when resolving an accessing ApiKeyPair to prevent NPEs.
  • Handle missing ApiKeyPair results in permission-resolution logic and improve related logging.
  • Fix getUserByApiKey to avoid dereferencing a null key pair.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadserver/src/main/java/com/cloud/user/AccountManagerImpl.java
Comment threadserver/src/main/java/com/cloud/user/AccountManagerImpl.java
Comment threadserver/src/main/java/com/cloud/user/AccountManagerImpl.java
Comment threadserver/src/main/java/com/cloud/user/AccountManagerImpl.java
CopilotAI review requested due to automatic review settings July 8, 2026 09:19
@sureshanaparti

Copy link
Copy Markdown
ContributorAuthor

@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.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 4 comments.

Comment on lines 3204 to 3206
ApiKeyPair accessingKeyPair = apiKeyPairService.findByApiKey(accessingApiKey);
if (userId == accessingKeyPair.getUserId()) {
if (accessingKeyPair != null && userId == accessingKeyPair.getUserId()) {
keyPair = apiKeyPairService.findByApiKey(accessingApiKey);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

As for this suggestion, we could apply it in this PR, if you're willing to, @sureshanaparti. But it is nitpicking IMO

Comment on lines +3341 to 3343
} catch (Exception e) {
logger.info("Error accessing API through session.", e);
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This Copilot suggestion does not make sense in the context of this method

Comment on lines +3589 to +3592
if (apiKeyPair == null) {
logger.warn("Unable to find API key pair by API key.");
return new ArrayList<>();
}
Comment on lines 3584 to 3588
public List<RolePermissionEntity> getAllKeypairPermissions(String apiKey) {
if (apiKey == null) {
throw new InvalidParameterValueException("API key not present in the request's URL and, thus, unable to fetch API key rules.");
}
ApiKeyPair apiKeyPair = keyPairManager.findByApiKey(apiKey);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This does not need to be applied in this PR

@blueorangutan

Copy link
Copy Markdown

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

if (accessingApiKey != null) {
ApiKeyPair accessingKeyPair = apiKeyPairService.findByApiKey(accessingApiKey);
if (userId == accessingKeyPair.getUserId()) {
if (accessingKeyPair != null && userId == accessingKeyPair.getUserId()) {

@weizhouapacheweizhouapacheJul 8, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It might be better to throw an exception here, if apikeypair is not found
similar to change with getAllKeypairPermissions method

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yes, it would be nice

@winterhazelwinterhazelJul 9, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
if (accessingKeyPair!= null && userId == accessingKeyPair.getUserId()) {
if (accessingKeyPair== null) {
thrownewCloudRuntimeException(String.format("Unable to find pair of API key [%s].", accessingApiKey));
}
if (userId == accessingKeyPair.getUserId()) {

@sureshanaparti it makes more sense to throw an exception here. Although unlikely, the way this if is structured right now can result in the key of user A of account X leaking when the caller is using a key to access user B of account X if accessingKeyPair is null.

}
ApiKeyPair apiKeyPair = keyPairManager.findByApiKey(apiKey);
if (apiKeyPair == null) {
logger.warn("Unable to find API key pair by API key.");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

throw an exception ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@sureshanaparti I would throw a CloudRuntimeException here as well. Even though this does not represent a security concern, returning an empty list here will allow the API call to finish "successfully", hiding an issue.

@weizhouapache

Copy link
Copy Markdown
Member

@sureshanaparti
can you share the steps to reproduce the issue ? thanks

@bernardodemarco

Copy link
Copy Markdown
Member

@winterhazel, before merging this, could you review it again, please?

@weizhouapache

Copy link
Copy Markdown
Member

@winterhazel@bernardodemarco@sureshanaparti
is this a critical issue for 4.23 ?

@winterhazel

winterhazel commented Jul 10, 2026

Copy link
Copy Markdown
Member

@winterhazel@bernardodemarco@sureshanaparti is this a critical issue for 4.23 ?

@weizhouapache I don't think so, although it would be nice to fix it for 4.23. I was only able to reproduce it by configuring valid username + password credentials for a profile in CMK, alongside an invalid API key.

(test) 🐱 >set apikey WpsOEhOzpJHDlo-RM7yezDdj5I_0o10GsqwCa9SF8sW8VeGHXLUY0X2THwOHNR7mVWup02SpS6-7JdCJrGYtNw
Loaded in-built API cache. Failed to read API cache, please run 'sync'.
(test) 🐱 >set secretkey GRiS1DJ7ToI1r8bJ5VDdzCAx_KSrnfcr3GZeMLEm0bNdTSSOe852_wHW74YdER_7mbShn09D-E5NoYxejQ6t_Q
Loaded in-built API cache. Failed to read API cache, please run 'sync'.
(test) 🐱 > sync
Discovered 889 APIs
(test) 🐱 >set apikey WpsOEhOzpJHDlo-RM7yezDdj5I_0o10GsqwCa9SF8sW8VeGHXLUY0X2THwOHNR7mVWup02SpS6-7JdCJrGYtN
(test) 🐱 > sync
🙈 Error: failed to authenticate, please check the credentials
(test) 🐱 >set username admin
(test) 🐱 > sync
🙈 Error: failed to authenticate, please check the credentials
(test) 🐱 >set password password
(test) 🐱 > sync
🙈 Error: (HTTP 530, error code 9999) Cannot invoke "org.apache.cloudstack.acl.apikeypair.ApiKeyPair.getAccountId()" because "apiKeyPair" is null

Using either (1) only username + password, (2) only API key + secret key, (3) username + password + valid API key does not result in any exceptions.

@weizhouapache

Copy link
Copy Markdown
Member

@winterhazel@bernardodemarco@sureshanaparti is this a critical issue for 4.23 ?

@weizhouapache I don't think so, although it would be nice to fix it for 4.23. I was only able to reproduce it by configuring valid username + password credentials for a profile in CMK, alongside an invalid API key.

(test) 🐱 >set apikey WpsOEhOzpJHDlo-RM7yezDdj5I_0o10GsqwCa9SF8sW8VeGHXLUY0X2THwOHNR7mVWup02SpS6-7JdCJrGYtNw
Loaded in-built API cache. Failed to read API cache, please run 'sync'.
(test) 🐱 >set secretkey GRiS1DJ7ToI1r8bJ5VDdzCAx_KSrnfcr3GZeMLEm0bNdTSSOe852_wHW74YdER_7mbShn09D-E5NoYxejQ6t_Q
Loaded in-built API cache. Failed to read API cache, please run 'sync'.
(test) 🐱 > sync
Discovered 889 APIs
(test) 🐱 >set apikey WpsOEhOzpJHDlo-RM7yezDdj5I_0o10GsqwCa9SF8sW8VeGHXLUY0X2THwOHNR7mVWup02SpS6-7JdCJrGYtN
(test) 🐱 > sync
🙈 Error: failed to authenticate, please check the credentials
(test) 🐱 >set username admin
(test) 🐱 > sync
🙈 Error: failed to authenticate, please check the credentials
(test) 🐱 >set password password
(test) 🐱 > sync
🙈 Error: (HTTP 530, error code 9999) Cannot invoke "org.apache.cloudstack.acl.apikeypair.ApiKeyPair.getAccountId()" because "apiKeyPair" is null

Using either (1) only username + password, (2) only API key + secret key, (3) username + password + valid API key does not result in any exceptions.

cool, thanks
I actually tried these 3 cases but was not able to reproduce the issue.

Since this is not a critical issue, 4.23 RC will not be blocked by it

@DaanHoogland

Copy link
Copy Markdown
Contributor

@bernardodemarco , you are marked as requesting changes, can you check?

@DaanHoogland

Copy link
Copy Markdown
Contributor

@weizhouapache should we merge for rc2? (assuming we get one)

@bernardodemarco

bernardodemarco commented Jul 20, 2026

Copy link
Copy Markdown
Member

@bernardodemarco , you are marked as requesting changes, can you check?

Hello, @DaanHoogland

Yes, @winterhazel and I have already reviewed the most recent changes of the PR. We are awaiting for updates to review again

@winterhazel

Copy link
Copy Markdown
Member

@weizhouapache should we merge for rc2? (assuming we get one)

@DaanHoogland assuming that it is ready for merge before the creation of RC2, yes. It is not a blocker issue though.

@sureshanaparti are you able to work on the requested changes this week?

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.

8 participants

@sureshanaparti@blueorangutan@winterhazel@bernardodemarco@DaanHoogland@weizhouapache@kiranchavala