There is no (known) secret key for a contract's account id. This is kind of the point of contracts: Their actions are governed by code rather than by an external force that can provide a signature.
There can't be a signature that is provided by a contract ever. The only way to have a specific contract appear as a caller somewhere is to make this contract execute the call. How do you do that? That depends completely on the contract in question. That is: Is the contract coded in a way to allow the interaction you want? The answer is usually "yes" because the contract author had a specific workflow in mind when putting the requirements in place.
In your concrete example we require the contract itself to call
add_owner because it is a privileged operation. Those must only be performed if enough owners want it to happen. If this is the case they can act on behalf of the contract (this is the basic multisig functionality). They do that by submitting a transaction that adds an owner, approve it and finally execute it. The workflow would look like this:
- Encode a
Transaction that calls
add_owner and pass it to
submit_transaction. Please note that you need to set
allow_reentrancy to true as the contract will be calling itself.
- Make enough owners call
confirm_transaction on the
TransactionId returned by your call to
submit_transaction in step 1.
invoke_transaction on the
TransactionId. This will make the contract call
add_owner on itself.
Transaction in step 1 requires the metadata in order to look up the selector and how to encode inputs. It is also a manual process. I think it would be worthwhile to standardize a
Call type in the contract metadata so that a nice UI could be build in case a call needs to be passed as argument.