A Solana program is code stored on chain. Whether that code can change depends on how it was deployed.
| How it was deployed | Can the code change? |
|---|---|
| Upgradeable loader, with an upgrade authority | Yes. The authority can deploy new code at any time. |
| Upgradeable loader, authority removed | No. The program is immutable, permanently. |
| Native program or the old non-upgradeable loader | Only through a network upgrade (native), or never (old loader). |
For the upgradeable loader, the program account points to a ProgramData account. That account records the upgrade authority and the slot of the last deploy, so both are public.
When you approve a transaction, you trust the code of every program it calls. With an upgradeable program you also trust whoever holds the upgrade authority: a single key, a multisig or a governance program. Frequent upgrades are normal for an actively developed protocol; what matters is who can make them.
Related: transfer hooks call a program on every transfer, so the same question applies to them.